一旦SetCacheability方法设置了,就可以删除Pragma no-cache响应头吗?

时间:2012-10-11 13:38:20

标签: asp.net-mvc-4

我有一个返回FileStreamResult的MVC4 GET操作方法。存在一种要求,即仅使用SSL并且不允许缓存所提供的文档,因此使用SSL,并且我还使用了具有以下属性的OutputCache过滤器:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None", Location = OutputCacheLocation.None)]

此行为符合预期,并生成以下响应标头:

Cache-Control: no-cache, no-store
Expires: -1
Pragma: no-cache

一直都很好,直到被要求也支持IE8,并且这里的许多人也遇到了文件,不会同时下载no-cache set和SSL。 IE8及以下的解释是添加一些不可行的注册表设置,或者删除违反基本要求的无缓存标头。

我尝试使用Fiddler和IE8并且能够下载文件,如果我刚删除了pragma:no-cache标头但保留了Cache-Control。这似乎没有在我的临时互联网文件中留下文档的副本,但我可能需要对此进行更多测试。

考虑到这些信息,我认为使用操作过滤器删除pragma可能是一项简单的任务,但似乎无论我做什么,我都无法更改OutputCache要设置的内容。我甚至删除了OutputCache属性并使用了:

Response.Cache.SetCacheability(HttpCacheability.NoCache)

单独使用此方法可确保我获得与以前相同的缓存设置,但不会在此方法调用时设置它们。这只是设置缓存策略,该策略在响应管道中的某个点应用,但我只是不知道在哪里。

有没有人知道是否有一种方法可以在响应管道中挂钩以在写入时更改缓存头?

修改 我在管道中添加了一个简单的自定义IHttpModule,它在响应NameValueCollection中查找并删除任何Pragma头,并且在设置缓存控件时,pragma不存在。这是否意味着IIS 7.5正在根据它在缓存控件中看到的内容插入pragma本身?我知道我没有为一个简单的网站设置任何超出默认值的内容。

修改 检查模块中的Cache-Control标头值并将其设置为private,以便尚未将缓存标头应用于响应。因此,在执行模块后,似乎会添加缓存标头?

1 个答案:

答案 0 :(得分:0)

我正在解决同样的问题并遇到了删除pragma标头的相同问题。当.NET呈现Page对象时,它会输出缓存头。缓存处理由HttpModule控制。我已经尝试了几种方法来删除pragma标头,但无济于事。

我还没有尝试过一种看起来可行的方法,但看起来PITA也是通过ResponseResponse.Filter = new MyCustomFilter(...)输出流上实现过滤器。

在此之前,我尝试检查各个位置的标头,但输出缓存处理尚未执行,并且pragma标头不存在,因此无法删除。值得注意的是,HttpApplication事件PreSendRequestHeaders不起作用。

其他一些选项包括实现自己的OutputCache模块而不是使用内置框架版本,或以某种方式覆盖提交pragma标头的System.Web.HttpCachePolicy类。

pragma标头作为HttpCacheability.NoCache选项的一部分呈现:

  if (httpCacheability == HttpCacheability.NoCache || httpCacheability == HttpCacheability.Server)
  {
    if (HttpCachePolicy.s_headerPragmaNoCache == null)
      HttpCachePolicy.s_headerPragmaNoCache = new HttpResponseHeader(4, "no-cache");
    this._headerPragma = HttpCachePolicy.s_headerPragmaNoCache;
    if (this._allowInHistory != 1)
    {
      if (HttpCachePolicy.s_headerExpiresMinus1 == null)
        HttpCachePolicy.s_headerExpiresMinus1 = new HttpResponseHeader(18, "-1");
      this._headerExpires = HttpCachePolicy.s_headerExpiresMinus1;
    }
  }

我发现唯一实用的选项是将缓存控制设置为私有,并为URL设置一个短暂的过期。它没有解决两端的根本原因,但它最终会产生几乎相同的预期效果。