asp.net中js合并,压缩
紧接着上一篇文章js文件 合并 压缩 去掉重复引用 缓存 延迟加载来说,遗留了一个很大的问题那就是js文本怎么合并与压缩了,上一篇文章中的
[csharp]
public static void appendjsfile(this htmlhelper htmlhelper, string jsfile, int group = 1)
public static mhtmlstring renderjsfile(this htmlhelper htmlhelper)
都只限于mvc中使用,我们能不能搞一个更通用的东东了,答案是肯定的。
先说说思路吧,其实很简单 就是我们自己接管输出流,如何接管了?在global.asax文件中添加以下代码:
[csharp]
public override void init()
{
base.init();
this.releaserequeststate += new eventhandler(installresponsefilter);
}
private void installresponsefilter(object sender, eventargs e)
{
httpresponse response = httpcontext.current.response;
if (response.contenttype == "text/html")
response.filter = new pagefilter(response.filter);
}
我还是沿用先前的项目做demo吧
和我们平时的开发没有任何区别,但是返回结果却是如下
我们看到js文件和js文本都合并 并且也是压缩了的。
关键的一切还是pagefilter的功劳啊
代码如下:
[html]
public class pagefilter : stream
{
stream responsestream;
long position;
stringbuilder responsehtml;
public pagefilter(stream inputstream)
{
responsestream = inputstream;
responsehtml = new stringbuilder();
}
#region filter overrides
public override bool canread
{
get { return true; }
}
public override bool canseek
{
get { return true; }
}
public override bool canwrite
{
get { return true; }
}
public override void close()
{
responsestream.close();
}
public override void flush()
{
responsestream.flush();
}
public override long length
{
get { return 0; }
}
public override long position
{
get { return position; }
set { position = value; }
}
public override long seek(long offset, seekorigin origin)
{
return responsestream.seek(offset, origin);
}
public override void setlength(long length)
{
responsestream.setlength(length);
}
public override int read(byte[] buffer, int offset, int count)
{
return responsestream.read(buffer, offset, count);
}
#endregion
#region dirty work
public override void write(byte[] buffer, int offset, int count)
{
httpresponse response = httpcontext.current.response;
string charset = response.charset ?? "utf-8";
string strbuffer = encoding.getencoding(charset).getstring(buffer, offset, count);
int bodyindex = strbuffer.tolower().lastindexof("</body>");
//js文本
regex reg = new regex("<script[^>]*>(?<content>[^<]*)</script>",regexoptions.ignorecase|regexoptions.multiline);
//js引用
regex regsrc = new regex("src=\"?(?<src>[^'\">]*)\"?",regexoptions.ignorecase|regexoptions.multiline);
stringbuilder jscontent = new stringbuilder();
list<string> jssrc = new list<string>();
matchcollection mc = reg.matches(strbuffer);
if (mc.count > 0)
{
#region 找出js部分
foreach (match m in mc)
{
string str = m.groups["content"].value;
if (!string.isnullorempty(str))
{
jscontent.appendline(str);//找出js文本
}
else
{
//找出js引用
match msrc = regsrc.match(m.value);
if (msrc != null && msrc.success)
{
string temp = msrc.groups["src"].value;
if (!jssrc.contains(temp))
jssrc.add(temp);
}
}
}
#endregion
strbuffer = reg.replace(strbuffer, string.empty);
if (bodyindex < 0)
{
//html 文档还没有结束
mergerjs(jscontent, jssrc);
}
else
{
#region 带结束标签的html
mergerjs(jscontent, jssrc);
//生成新的js引用
string jsfileformat = "<script type=\"text/javascript\" src=\"{0}\"></script>";
string jshref = string.format(jsfileformat, "=" + string.join(",", jssrc));
//生成新的js文本
string jstextformat = "<script type=\"text/javascript\">{0}</script>";
//压缩js文本
string jscontentstr = javascriptcompressor.compress(jscontent.tostring());
string jstext = string.format(jstextformat, jscontentstr);
//插入新生成的js
bodyindex = strbuffer.tolower().lastindexof("</body>");
strbuffer = strbuffer.insert(bodyindex, jshref + environment.newline + jstext);
#endregion
}
byte[] data = encoding.getencoding(charset).getbytes(strbuffer);
responsestream.write(data, 0, data.length);
}
else {
responsestream.write(buffer, offset, count);
}
}
void mergerjs(stringbuilder jscontent, list<string> jssrc)
{
string jstextkey = "jstextkey";
string jsfilekey = "jsfilekey";
if (!httpcontext.current.items.contains(jstextkey))
httpcontext.current.items.add(jstextkey, jscontent);
else
{
stringbuilder jstexttemp = httpcontext.current.items[jstextkey] as stringbuilder;
jscontent.insert(0, jstexttemp.tostring());
}
if (!httpcontext.current.items.contains(jsfilekey))
httpcontext.current.items.add(jsfilekey, jssrc);
else
{
list<string> jsfiletemp = httpcontext.current.items[jstextkey] as list<string>;
jssrc.insertrange(0, jsfiletemp);
}
}
#endregion
}
说了这么多,这里只是提供一个思想,一个js合并的思想,在真实的项目中还有很多细节需要注意啊。
摘自 dz45693的专栏
上一篇: 去旅行如何打包行李?
下一篇: Oracle常用管理语句记录
推荐阅读