IIS 7.5强制http头CacheControl为Private



在我的。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被强制为private。这是我得到的:

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更改为private

这是我的web服务器部分。配置:

<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在这里提到的缓存。SetMaxAge在IIS下不工作,在VS Dev Srv下工作得很好,但没有帮助。

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

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

它看起来很脏,但似乎响应。CacheControl和响应。IIS在集成模式下未使用缓存属性(或被某些模块覆盖…)

默认值在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";
        }

Update:设置cache-control将禁用bundle的缓存。我现在使用以下解决方案。它仅在未显式设置时更改页面的可缓存性。默认值'6'来自这里:

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

此外,当出现错误并且通过ReportRuntimeError呈现YSOD(黄色错误页)时,框架将调用ClearHeaders,并且您的自定义缓存控制设置将被覆盖。

最新更新