jjzjj

c# - 无法将 'Vary' header 附加到响应

coder 2024-06-01 原文

我正在尝试将 Vary: Accept-Encoding header 添加到对我压缩的文件的响应中,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");

    }
}

这会产生以下响应 header :

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 header 不存在。存在具有相似语法的无意义 header ,因此在发送 Vary header 之前必须在某处删除它。

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

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

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

为什么我无法添加 Vary header ?

编辑: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, CompressionMode.Compress);
        app.Response.AppendHeader("Content-Encoding", "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

(不知道为什么这是 application/x-javascript,因为它在 HTML 中设置为 text/javascript,但这无关紧要。)

如您所见,我现在有一个 vary header ,但它被设置为 Vary=* 而不是 Vary=Accept-Encoding,正如您期望的那样我在压缩模块中的代码。

这是怎么回事?如何正确设置 Vary header ?

第二次编辑: 我将粘贴整个类(class)的源代码。除了我已经发布的内容之外,没有更多内容,但它可能有助于准确掌握我在做什么:

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, CompressionMode.Compress);
                app.Response.AppendHeader("Content-Encoding", "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>

没有更多要说的了。据我所知,我们在网站上没有做其他非标准的事情。有什么想法吗?

最佳答案

从 IIS 7.5 开始,Vary header 被实现 DyanamicCompressionModule 的 gzip IIS 过滤器 (gzip.dll) 覆盖。过滤器始终将 header 设置为“Vary: Accept-Encoding”,而不管 ASP.NET 代码中所做的更改。到今天为止,唯一的解决方法是禁用动态内容的压缩,然后在代码中实现它。方法如下:

  1. 从 Web.config 中删除以下行:

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

  2. 然后转到 IIS 管理控制台并确保没有为动态内容启用压缩。

  3. Global.asax.cs 中手动实现压缩, 方法 HttpApplication.Application_BeginRequest :

   protected void Application_BeginRequest(object sender, EventArgs e)
   {
       HttpContext context = HttpContext.Current;
       context.Response.Filter 
          = new GZipStream(context.Response.Filter, CompressionMode.Compress);
       context.Response.AppendHeader("Content-Encoding", "gzip");
       context.Response.Cache.VaryByHeaders["Accept-Encoding"] = true;

       // We can now set additional Vary headers...
       context.Response.Cache.VaryByHeaders.UserAgent = true;
       context.Response.Cache.VaryByHeaders["X-Requested-With"] = true;
   }

这是最近的一个问题 reported to Microsoft .

关于c# - 无法将 'Vary' header 附加到响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7849392/

有关c# - 无法将 'Vary' header 附加到响应的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  4. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  5. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  6. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  7. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  8. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  9. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  10. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

随机推荐