科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道ASP.NET AJAX 资源脚本压缩的秘密

ASP.NET AJAX 资源脚本压缩的秘密

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

    从ATLAS到正式的ASP.NET AJAX已经发生了根本性的变化了,所以当时的情况就不再多做介绍了.还是先来看看一组数据 Resource Name DEBUG Uncompressed DEBUG Co在ASP.NET中上传图片并生成缩略图的C

作者:中国IT实验室 来源:中国IT实验室 2007年10月2日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
  

 其中,zip参数是用于指定是否生成带有压缩版本的URL地址,如果zip为true,则返回的参数d的第一个字符为Z或z。否则为U或u。具体是如何去压缩的,我们现在先不管,反正URL地址中的地址栏参数d的第一字符为Z或z就表明访问的资源被请求到客户端前会被压缩。因此要访问压缩的脚本资源,就要保证zip参数为true。那这个参数从何而来呢?它是由ScriptManager的Zip属性原原本本的被传递到这个方法中,这在传递的过程当中没有被修改过。而ScriptManager的Zip的属性定义如下:


internal bool Zip{
get
{
if (!this._zipSet)
{
this._zip = HeaderUtility.IsEncodingInAcceptList(this.IPage.Request.Headers["Accept-encoding"], "gzip");
this._zipSet = true;
}
return this._zip;
}
}
code
2

 决定它值的是客户端HTTP请求头部是否带有Accept-Encoding: gzip。因此大部分的浏览器都支持GZIP压缩过的HTTP输出流程,因此大部份浏览器的请求头部都会有这么一段:Accept-Encoding: gzip, deflate。因此这个值在接受IE6请求时,应该是为true才对的,而它得到的应该也是个压缩版本的资源URL请求才对啊?除非CODE1中的zip参数被改为false了。再回过头来看CODE1的开始部分有这么一段代码:

if (!ScriptResourceHandler.IsCompressionEnabled(HttpContext.Current))
{
zip
= false;
}
code 
3

 只有在这里zip的值才有可能被修改为false,那我们再来看看,ScriptResourceHandler.IsCompressionEnabled究竟做了此什么了?

private static bool IsCompressionEnabled(HttpContext context)
{
if (!ScriptingScriptResourceHandlerSection.ApplicationSettings.EnableCompression)
{
return false;
}
if ((context != null) && context.Request.Browser.IsBrowser("IE"))
{
return (context.Request.Browser.MajorVersion > 6);
}
return true;
}
code
4

 第一,我们可以确定EnableCompression的值为true。第二,我们使用的是IE,会执行return (context.Request.Browser.MajorVersion > 6) ,因为我们使用的IE6,这边就会返回false。回到CODE 3,zip的值就会被修改成false了。而此时就会返回不被压缩的URL地址了。问题就在这里,可这是为什么呢?我想一般情况下我们肯定会不理解的,看了这个你就清楚了:http://www.microsoft.com/downloads/details.aspx?familyid=85bb441a-5bb1-4a82-86ec-a249af287513&displaylang=en 原来在IE6的SP1版本中,接收GZIP的数据会有问题,而这边就是给了解决这个问题的补丁包。ASP.NET AJAX团队,可能担心由于这个问题引起的部分IE浏览器无法正常使用ASP.NET ajax,保险起见,在IE6的请求中永不使用压缩脚本。

 分析了代码,为了让我们有更直观的印象,再来看一段代码例子:

protected void Page_Load(object sender, EventArgs e)
{
NameValueCollection queryString
= HttpUtility.ParseQueryString(GetScriptResourceUrl());
Response.Write(DecryptString(queryString[
0]));
}
private static string DecryptString(string s)
{
MethodInfo _decryptString
= typeof(Page).GetMethod("DecryptString", BindingFlags.NonPublic | BindingFlags.Static);
return (string)_decryptString.Invoke(null, new object[] { s });
}
private string GetScriptResourceUrl()
{
MethodInfo GetScriptResourceUrl
= typeof(ScriptManager).GetMethod("GetScriptResourceUrl", BindingFlags.NonPublic | BindingFlags.Instance);
 
return (string)GetScriptResourceUrl.Invoke(sm, new object[]
{
"MicrosoftAjax.js", sm.GetType().Assembly
}
);
}

 在IE6,它输出的是 USystem.Web.Extensions|MicrosoftAjax.js| ,而在FF中它输出的是:ZSystem.Web.Extensions|MicrosoftAjax.js|

 这两个不同的输出值完全就可以体现了它们请求行为的不同。

 接下来,简单讨论一下,我们如何修改让它去掉这个限制。在ScriptResourceHandler有一个这样的静态方法SetScriptResourceHandler,我们可以重新实现一个IScriptResourceHandler类,用这个法植入到ASP.NET AJAX内部,让它们使用。但问题是SetScriptResourceHandler是一个internal的方法,使用反射呗,那还能怎么样,谁让它这样设计,既提供这个方法,又不想让人用!

 OK,对这个问题的研究就先到这边了。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章