【问题标题】:IIS 7.5 forces the http header CacheControl to PrivateIIS 7.5 强制 http 标头 CacheControl 为 Private
【发布时间】:2013-03-26 18:39:05
【问题描述】:

在我的 .NET 代码中,我有一个处理 Http 请求的自定义处理程序,并且在 ProcessRequest 方法中调用一个自定义 HttpModule 来设置 Http 缓存标头。

HttpModule 使用以下代码在 PreSendRequestHeaders 方法中设置标头

HttpCachePolicy cache = response.Cache;
if (cache != null)
{
  cache.SetCacheability(HttpCacheability.Public);
  cache.SetMaxAge(TimeSpan.FromSeconds(varnishDuration));
  response.AppendHeader("Edge-control", String.Concat("!no-store, max-age=", akamaiDuration, "s dca=noop"));
}

在 IIS 7.5 中,当池处于集成模式时,CacheControl 被强制为私有。 这是我得到的:

curl -IXGET -H "Host:myHostName" "http://myServer/mypage"
HTTP/1.1 200 OK
Cache-Control: private
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
Edge-control: !no-store, max-age=300s dca=noop
[...]

我不明白为什么 IIS 将 CacheControl 更改为私有。

这是我的 web.config 中的网络服务器部分:

<pre>
<system.webServer>
    <handlers accessPolicy="Read, Script">
      <add name="OxygenHandler" verb="*" path="*" type="com.eurosport.oxygen.server.modules.OxygenHandlerFactory, OxygenServerModules" />
    </handlers>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="WebServiceCachingModule" type="com.eurosport.toolkit.WebServiceCachingModule, Eurosport.Toolkit" />
    </modules>
  </system.webServer>
</pre>

我尝试添加此处提到的 SetSlidingExpiration Cache.SetMaxAge not working under IIS, works fine under VS Dev Srv,但没有帮助。

【问题讨论】:

    标签: iis http-headers iis-7.5 cache-control integrated-pipeline-mode


    【解决方案1】:

    我已经设法让它在我的模块中使用以下代码:

    response.Headers.Remove("Cache-Control");
    response.AppendHeader("Cache-Control", "public, max-age=" + varnishDuration.ToString()+", s-max-age=" + varnishDuration.ToString());
    

    它看起来很脏,但似乎 response.CacheControl 和 response.Cache 属性在集成模式下未被 IIS 使用(或被某些模块覆盖......)

    【讨论】:

      【解决方案2】:

      默认在System.Web.HttpResponse.CacheControl中指定:

              /// <devdoc>
              ///    <para>
              ///       Provided for ASP compatiblility. Use the <see cref='System.Web.HttpResponse.Cache'/>
              ///       property instead.
              ///    </para>
              /// </devdoc>
              public string CacheControl {
                  get {
                      if (_cacheControl == null) {
                          // the default
                          return "private";
                      }
      
                      return _cacheControl;
                  }
      

      虽然您可以通过(全局)过滤器覆盖标头,但这不适用于由身份验证/授权引起的错误页面。 幸运的是,每个请求都有一个不错的入口点,允许您覆盖此默认值:

      // In Global.asax.cs:
              protected void Application_BeginRequest()
              {
                  Context.Response.CacheControl = "no-cache";
              }
      

      更新:根据上述设置缓存控制将禁用捆绑包的缓存。我现在正在使用以下解决方法。它仅在未显式设置时更改页面的可缓存性。 '6'的默认值来自here

      // In Global.asax.cs:
              protected void Application_EndRequest()
              {
                  if ((int)Response.Cache.GetCacheability() == ((int)HttpCacheability.ServerAndPrivate) + 1)
                      Response.Cache.SetCacheability(HttpCacheability.NoCache);
              }
      

      此外,当出现错误并且 YSOD(黄色错误页面)通过 ReportRuntimeError 呈现时,框架将调用 ClearHeaders 并且您的自定义缓存控制设置将被覆盖。我还没有找到解决方案。

      【讨论】:

        猜你喜欢
        • 2013-11-18
        • 1970-01-01
        • 2012-08-13
        • 2012-06-05
        • 2020-05-26
        • 2015-10-18
        • 2011-12-18
        • 2021-02-19
        • 1970-01-01
        相关资源
        最近更新 更多