如何在ASP.NET中实现GZip压缩?


81

我正在尝试为我的asp.net页(包括CSS和JS文件)实施GZip压缩。我尝试了以下代码,但它仅压缩我的.aspx页(从YSlow找到)

HttpContext context = HttpContext.Current;
context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
HttpContext.Current.Response.AppendHeader("Content-encoding", "gzip");
HttpContext.Current.Response.Cache.VaryByHeaders["Accept-encoding"] = true;

上面的代码仅压缩我的.aspx页面代码(标记),而不压缩作为外部文件包含的CSS和JS文件。请告诉我如何使用代码在ASP.NET中实现GZip压缩(因为我位于共享主机服务器上,而我无法访问IIS服务器配置)。而且在上面的代码中,我没有得到最后两行,为什么要使用它们以及这些行的目的是什么。请解释!


Answers:


28

对于压缩JS和CSS文件,您实际上必须在IIS级别进行处理,因为这些文件无需ASP.NET运行时即可直接呈现。

您可以在IIS中将JSX和CSSX扩展名映射到aspnet_isapi.dll,然后利用邮政编码,但IIS可能会为您做得更好。

内容编码标头告诉浏览器在呈现之前需要解压缩内容。有些浏览器很聪明,可以根据内容的形状来解决这个问题,但是最好告诉它。

此处有“接受编码缓存”设置,因此不会将gzip压缩内容的缓存版本发送到仅请求text / html的浏览器。


4
嗨,@ Ben,您能告诉我如何使用IIS压缩文件吗,我必须执行的所有设置是什么,虽然我无权访问IIS配置,但我会尽力做到这一点。请告诉我如何使用IIS压缩文件?谢谢!
Prashant

4
stackoverflow.com/a/6992948/8479详细介绍了IIS7或更高版本需要对web.config进行的简单更改。
罗里

47

这是CSS和javascript文件的解决方案。将以下代码添加到您的web.config文件中:

  <httpCompression>
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
    <dynamicTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </dynamicTypes>
    <staticTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </staticTypes>
  </httpCompression>
  <urlCompression doStaticCompression="true" doDynamicCompression="true"/>

信用:如何在ASP.NET和GoDaddy上进行GZip


4
最后一行应删除
JeffT

是的,但实际上我会添加开头<system.webServer> ...,以便我们知道将配置放在何处。
卡洛斯·R·巴尔波纳

我添加了相同的代码,但文件没有得到压缩
Zeeshan Ahmad Khalil

我是否需要添加其他内容?
Zeeshan Ahmad Khalil

16

这对于您尝试一下可能很有用,它接受deflate和gzip压缩。

    void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;
        string acceptEncoding = app.Request.Headers["Accept-Encoding"];
        Stream prevUncompressedStream = app.Response.Filter;

        if (app.Context.CurrentHandler == null)
            return;

        if (!(app.Context.CurrentHandler is System.Web.UI.Page ||
            app.Context.CurrentHandler.GetType().Name == "SyncSessionlessHandler") ||
            app.Request["HTTP_X_MICROSOFTAJAX"] != null)
            return;

        if (acceptEncoding == null || acceptEncoding.Length == 0)
            return;

        acceptEncoding = acceptEncoding.ToLower();

        if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
        {
            // deflate
            app.Response.Filter = new DeflateStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "deflate");
        }
        else if (acceptEncoding.Contains("gzip"))
        {
            // gzip
            app.Response.Filter = new GZipStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "gzip");
        }
    } 

2
非常感谢此代码。我需要将内容gzip /压缩到一个我无法访问IIS控制台的特定站点,这对我有所帮助。不过,只是一个问题:该代码似乎压缩了所有的aspx文件并gziping CSS和ScriptResources,但没有gziping任何.js文件。有办法吗?谢谢。
拉斐尔·梅林

这是错误的,因为您没有像这样处理质量说明:gzip;q=0,deflatesingular.co.nz/2008/07/…–
oligofren

11

它仅压缩ASPX文件的原因是,您编写的代码仅嵌入在ASPX文件中。ASPX文件是与其包含的任何链接内容分开的请求。因此,如果您的ASPX页面包含:

<img src="www.example.com\exampleimg.jpg" alt="example" />

从您的浏览器到资源的总计2个请求(除了DNS查找):

  1. 对于aspx页面和
  2. aspx页面包含的图像。

每个请求都有自己的响应流。您发布的代码仅附加到ASPX响应流,这就是仅压缩ASPX页面的原因。您发布的代码的第1行和第2行实际上是在接管页面的常规响应流,并注入一些“中间人”代码,在这种情况下,该代码会吃掉GZip流并压缩常规输出流,然后将其发送到网络上。

第3和4行设置响应头。所有http请求和响应均具有在内容之前发送的标头。这些设置请求/响应,以便服务器和客户端知道正在发送什么以及如何发送。

在这种情况下,第3行通知客户端浏览器,响应流是通过gzip压缩的,因此需要在显示之前由客户端浏览器解压缩。

第4行只是打开响应的Accept-Encoding标头。否则,答复中将没有此内容。

您可以编写/获取一些可插拔模块,这些模块可让您压缩* .js和* .css之类的其他MIME类型的多点传送,但是最好还是使用IIS的内置压缩功能。

您尚未说明正在使用哪个版本的IIS,但如果是IIS 7.0,则需要在<system.webserver>web.config文件的部分中包含以下内容:

<httpCompression> 
  <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" /> 
 <staticTypes>
         <add mimeType="text/*" enabled="true" />
      </staticTypes>
</httpCompression> 
<urlCompression doStaticCompression="true" /> 

..

理查德


真的很
糟糕的

3

在IIS7中,所有请求都转到.net,因此您必须创建一个HttpModule,将这些标头添加到所有响应中。

没有IIS7,并且在共享主机上,您将必须创建一个映射了未使用的.net文件扩展名的处理程序(例如.asmx),并在web.config中指定.asmx文件进入已设置的HttpHandler。重写.jpg或其他内容的路径,并在其中设置标题。


2

回答您的最后一个问题。这两行设置了发送回浏览器的响应的HTTP标头。Content-Encoding告诉浏览器,响应已编码为gzip,需要解码。最后一行添加Accept-EncodingVary标头中。借助此功能,浏览器或代理可以确定响应是唯一的还是受某些其他标头的影响,并调整其缓存。


0

将.aspx扩展名添加到.css或.js文件。在文件中使用<%@ Page ContentType =“ text / css”%>或javascript以正确的MIME类型为其提供服务。并使用“ URL重写”在用户代理浏览器中隐藏它。内容编码响应标头附加在gzip后面,以传达gzip是用于执行压缩的方法。每个响应标头都设置为Accept-Encoding,因此所有缓存都知道应为哪个页面(压缩或未压缩)提供服务,具体取决于请求的Accept-Encoding标头。我已经在https://stackoverflow.com/a/14509007/1624169上进行了详细说明



0

要么使用web.config文件

<system.webServer>
    <httpCompression>
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
        <dynamicTypes>
            <add mimeType="text/*" enabled="true"/>
            <add mimeType="message/*" enabled="true"/>
            <add mimeType="application/javascript" enabled="true"/>
            <add mimeType="*/*" enabled="false"/>
        </dynamicTypes>
        <staticTypes>
            <add mimeType="text/*" enabled="true"/>
            <add mimeType="message/*" enabled="true"/>
            <add mimeType="application/javascript" enabled="true"/>
            <add mimeType="*/*" enabled="false"/>
        </staticTypes>
    </httpCompression>
    <urlCompression doStaticCompression="true" doDynamicCompression="true"/>
</system.webServer>

或者,您可以通过IIS来实现。对于压缩JS和CSS文件,您实际上必须在IIS级别进行处理,因为这些文件无需ASP.NET运行时即可直接呈现。

您可以在IIS中将JSX和CSSX扩展名映射到aspnet_isapi.dll,然后利用邮政编码,但IIS可能会为您做得更好。

内容编码标头告诉浏览器在呈现之前需要解压缩内容。有些浏览器很聪明,可以根据内容的形状来解决这个问题,但是最好告诉它。

此处有“接受编码缓存”设置,因此不会将gzip压缩内容的缓存版本发送到仅请求text / html的浏览器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.