【问题标题】:Unable to set both GzipStream and Content-Encoding to gzip on the same response无法在同一响应上将 GzipStream 和 Content-Encoding 都设置为 gzip
【发布时间】:2014-01-09 19:31:50
【问题描述】:

我正在开发一个要在 web.config 中使用的 CompressionModule,我已经将一个更大的问题分解到这个案例中,这让我很困惑。

对于这个示例,我创建了一个新的 MVC4 互联网应用程序并对 web.config 进行了以下修改:

<handlers>
  <!--
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  -->
  <add name="Content" path="*" verb="*" preCondition="integratedMode" type="System.Web.StaticFileHandler" />
</handlers>
<modules>
        <remove name="monorailRouting" />
      <add name="compressionModule" type="Platform.Web.CompressionModule" />
  <!--
  <add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      -->
</modules>

压缩模块在哪里

namespace Platform.Web {
public class CompressionModule : IHttpModule {

    #region HTTP Header Constants
    private const string DEFLATE = "deflate";
    private const string GZIP = "gzip";
    private const string CONTENT_ENCODING = "Content-Encoding";
    private const string ACCEPT_ENCODING = "Accept-Encoding";
    private const string VARY = "Vary";
    #endregion

    #region IHttpModule Members
    public void Dispose() {
        //noop
    }

    public void Init(HttpApplication context) {
        context.BeginRequest += new EventHandler(context_CompressResponse);
    }


    void context_CompressResponse(object sender, EventArgs e) {
        HttpApplication app = (HttpApplication)sender;

        string encodings = app.Request.Headers.Get(ACCEPT_ENCODING);

        if (encodings == null)
        {
            return;
        }

        encodings = encodings.ToLower();

        if (encodings.Contains(GZIP))
        {
            //1
            app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);

            //2
            app.Response.AppendHeader(CONTENT_ENCODING, GZIP);

        }

        app.Response.AppendHeader(VARY, CONTENT_ENCODING);



    }

    #endregion
}
}

我遇到了以下问题:

  1. 如果存在第 1 行和第 2 行,则应用程序加载正常。但显然什么都不是 gzip压缩在标题中,也不在正文中。我正在通过 Fiddler 确定这一点。

  2. 如果第 1 行存在但第 2 行未加载应用程序但 gzip 不可读 显示在浏览器中。

  3. 如果第 1 行不存在但第 2 行存在,则应用程序无法加载但 内容编码:gzip 在标题中。

有人对我可能做错了什么有一些建议吗?

【问题讨论】:

    标签: c# .net gzip


    【解决方案1】:

    我认为应该在这里做两件事,

    1. 应将响应过滤器放入流的副本中
    2. 必须更改标头的变化

    试试下面的代码:

    void context_CompressResponse(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;
    
        string encodings = app.Request.Headers.Get(ACCEPT_ENCODING);
        if (encodings == null)
        {
            return;
        }
    
        encodings = encodings.ToLower();
    
        if (encodings.Contains(GZIP))
        {
            Stream baseStream = app.Response.Filter;
    
            //1
            app.Response.Filter = new GZipStream(baseStream, CompressionMode.Compress);
    
            //2
            app.Response.AppendHeader(CONTENT_ENCODING, GZIP);
        }
        Response.Cache.VaryByHeaders[ACCEPT_ENCODING] = true;
    }
    

    另外,如需进一步讨论,请查看此 SO article

    【讨论】:

    • 不行。我只是得到一个类似于我的第一个案例的未压缩响应。
    【解决方案2】:

    原来 Fiddler2 没有正确读取标题。

    如果我在 Chrome 中查看响应,我可以看到 Content-Encoding 被设置为 gzip。

    -杰夫

    【讨论】:

      猜你喜欢
      • 2017-09-21
      • 1970-01-01
      • 2016-08-27
      • 2017-09-02
      • 2023-03-10
      • 2023-03-14
      • 2015-12-13
      • 2014-09-09
      • 1970-01-01
      相关资源
      最近更新 更多