c# – 无法将“Vary”标头追加到响应中

前端之家收集整理的这篇文章主要介绍了c# – 无法将“Vary”标头追加到响应中前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试添加一个Vary:Accept-Encoding头到对我压缩的文件的响应,as advised earlier.

但是,由于某些原因,这是不可能的 – 无论是从Visual Studio测试服务器还是IIS服务器.

我有以下代码

if (url.Contains(".js") || url.Contains(".aspx") || url.Contains(".css"))
{
    app.Response.AppendHeader("Vary","Accept-Encoding");
    app.Response.AppendHeader("Varye","Accept-Encoding"); // for testing
    app.Response.AppendHeader("Varye","Accept-Things");   // for testing
    app.Response.AppendHeader("Vary","Accept-Stuff");     // for testing
    app.Response.AppendHeader("Var","Accept-Items");      // for testing

    encodings = encodings.ToLower();

    if (encodings.Contains("gzip") || encodings == "*")
    {
        app.Response.Filter = new GZipStream(baseStream,CompressionMode.Compress);
        app.Response.AppendHeader("Content-Encoding","gzip");

    }
}

这导致以下响应标题

Status=OK - 200
Server=ASP.NET Development Server/10.0.0.0
Date=Fri,21 Oct 2011 12:24:11 GMT
X-AspNet-Version=4.0.30319
Varye=Accept-Encoding,Accept-Things
Var=Accept-Items
Content-Encoding=gzip
Cache-Control=public
Etag="1CC8F2E9D772300"
Content-Type=text/css
Content-Length=16200
Connection=Close

您可以看到,Vary标题不存在.存在具有相似语法的无意义的头文件,因此在发送之前必须有某些东西取出Vary标题.

我不知道它是否相关,但这里是我在web.config中定义我的压缩模块的地方:

<httpModules>
    <add name="CompressionModule" type="Utility.HttpCompressionModule"/>
</httpModules>

(其中Utility.HttpCompressionModule是我上面提供的代码摘录所属的类.)

为什么我不能添加Vary标题

编辑:Eric C的解决方案给我留下了如下代码

if (url.Contains(".js") || url.Contains(".aspx") || url.Contains(".css"))
{
    app.Response.Cache.SetVaryByCustom("Accept-Encoding");

    encodings = encodings.ToLower();

    if (encodings.Contains("gzip") || encodings == "*")
    {
        app.Response.Filter = new GZipStream(baseStream,"gzip");

    }

但是,标题看起来像这样:

Status=OK - 200
Server=ASP.NET Development Server/10.0.0.0
Date=Mon,24 Oct 2011 09:26:37 GMT
Content-Encoding=gzip
Cache-Control=public
Etag="1CC7A09FDE77300"
Vary=*
Content-Type=application/x-javascript
Content-Length=44447
Connection=Close

(不知道为什么这是应用程序/ x-javascript作为其在HTML中设置为text / javascript,但这是无关紧要的.)

正如你所看到的,我现在有一个不同的标题,但是它被设置为Vary = *而不是Vary = Accept-Encoding,正如您从压缩模块中的代码所期望的那样.

这里发生了什么?如何正确地获取Vary标题

第二编辑:
我要粘贴整个类的源代码.没有比我已经发布的更多,但它可能有助于掌握正在做什么:

public class HttpCompressionModule : IHttpModule
{
    /// <summary>
    /// Initializes a new instance of the <see cref="AjaxHttpCompressionModule"/> class.
    /// </summary>
    public HttpCompressionModule()
    {
    }

    #region IHttpModule Members

    /// <summary>
    /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
    /// </summary>
    void IHttpModule.Dispose()
    {

    }

    /// <summary>
    /// Initializes a module and prepares it to handle requests.
    /// </summary>
    /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods,properties,and events common to all application objects within an ASP.NET application</param>
    void IHttpModule.Init(HttpApplication context)
    {
        context.BeginRequest += (new EventHandler(this.context_BeginRequest));
    }

    #endregion

    /// <summary>
    /// Handles the BeginRequest event of the context control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    void context_BeginRequest(object sender,EventArgs e)
    {            
        HttpApplication app = (HttpApplication)sender;
        string encodings = app.Request.Headers.Get("Accept-Encoding");
        Stream baseStream = app.Response.Filter;


        if (string.IsNullOrEmpty(encodings))
            return;


        string url = app.Request.RawUrl.ToLower();

        if (url.Contains(".js") || url.Contains(".css") || url.Contains("ajax.ashx"))
        {
            app.Response.Cache.SetVaryByCustom("Accept-Encoding");

            encodings = encodings.ToLower();

            if (encodings.Contains("gzip") || encodings == "*")
            {
                app.Response.Filter = new GZipStream(baseStream,CompressionMode.Compress);
                app.Response.AppendHeader("Content-Encoding","gzip");

            }
            else if (encodings.Contains("deflate"))
            {
                app.Response.Filter = new DeflateStream(baseStream,"deflate");
            }
        }
    }
}

此外,这是我的web.config文件的System.Web部分:

<system.web>
    <!--<compilation debug="true"></compilation>-->
    <trace enabled="true" traceMode="SortByTime"/>
    <httpRuntime executionTimeout="180"/>
    <globalization culture="en-GB" uiCulture="en-GB"/>
    <!-- custom errors-->
    <customErrors mode="Off">
    </customErrors>
    <!-- Membership -->
    <membership defaultProvider="sqlProvider" userIsOnlineTimeWindow="15">
        <providers>
            <clear/>
            <add name="sqlProvider" type="System.Web.Security.sqlMembershipProvider" connectionStringName="sqlServerAuth" applicationName="mycompany" minrequiredPasswordLength="4" minrequiredNonalphanumericCharacters="0" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="1024"/>
        </providers>
    </membership>
    <!-- Roles -->
    <roleManager enabled="true" cacheRolesInCookie="true" defaultProvider="sqlProvider">
        <providers>
            <clear/>
            <add connectionStringName="sqlServerAuth" applicationName="mycompany" name="sqlProvider" type="System.Web.Security.sqlRoleProvider"/>
        </providers>
    </roleManager>
    <!-- Authentication -->
    <anonymousIdentification enabled="false"/>
    <authentication mode="Forms">
        <forms name=".AUTH" protection="All" timeout="2" path="/">
        </forms>
    </authentication>
    <httpModules>
        <add name="CompressionModule" type="Utility.HttpCompressionModule"/>
    </httpModules>
</system.web>

没有什么可说的.我所了解的这个网站没有其他非标准的东西.有任何想法吗?

解决方法

如其他人所说,这是一个 known issue,IIS压缩模块专门覆盖Vary头,并已在 hotfix处理.

如果您无法确保该修补程序已安装,另一个解决方法是使用IIS URL Rewrite在Web.config中附加标题

<configuration>
  <system.webServer>
    <rewrite>
      <outboundRules>
        <rule name="Append 'Vary: X-Requested-With' header" patternSyntax="ECMAScript">
          <match serverVariable="RESPONSE_VARY" pattern=".+" />
          <action type="Rewrite" value="{R:0},X-Requested-With" replace="true" />
        </rule>
        <rule name="Set 'Vary: X-Requested-With' header if no others" patternSyntax="ECMAScript">
          <match serverVariable="RESPONSE_VARY" pattern=".+" negate="true" />
          <action type="Rewrite" value="X-Requested-With" />
        </rule>
      </outboundRules>
    </rewrite>
  </system.webServer>
</configuration>

猜你在找的C#相关文章