如何阻止Chrome缓存来自WebApi的REST响应?

15

我正在使用ASP.NET WebApi,并有以下代码来停止缓存:

public override System.Threading.Tasks.Task<HttpResponseMessage> ExecuteAsync(System.Web.Http.Controllers.HttpControllerContext controllerContext, System.Threading.CancellationToken cancellationToken)
{
    System.Threading.Tasks.Task<HttpResponseMessage> task = base.ExecuteAsync(controllerContext, cancellationToken);
    task.GetAwaiter().OnCompleted(() =>
                                      {
                                          task.Result.Headers.CacheControl = new CacheControlHeaderValue()
                                          {
                                              NoCache = true,
                                              NoStore = true,
                                              MaxAge = new TimeSpan(0),
                                              MustRevalidate = true
                                          };
                                          task.Result.Headers.Pragma.Add(new NameValueHeaderValue("no-cache"));
                                          task.Result.Content.Headers.Expires = DateTimeOffset.MinValue;
                                      });
    return task;
}

结果头看起来像这样(在Chrome中):

Cache-Control:no-store, must-revalidate, no-cache, max-age=0
Content-Length:1891
Content-Type:application/json; charset=utf-8
Date:Fri, 19 Jul 2013 20:40:23 GMT
Expires:Mon, 01 Jan 0001 00:00:00 GMT
Pragma:no-cache
Server:Microsoft-IIS/8.0

在阅读了关于这个 bug 的文章(如何停止 Chrome 缓存)后,我添加了 "no-store"。

然而,无论我做什么,当我从这个页面导航到其他页面,然后使用 "返回" 按钮时,Chrome 总是从缓存中加载:

Request Method:GET
Status Code:200 OK (from cache)

有人知道为什么会发生这种情况吗?我已确认该请求从未到达服务器。

1个回答

8
答案是Chrome不喜欢"Expires:Mon, 01 Jan 0001 00:00:00 GMT"(一种假日期)。
我将我的日期改为他们在Google API中使用的日期,然后就可以正常工作了:
Cache-Control:no-store, must-revalidate, no-cache, max-age=0
Content-Length:1897
Content-Type:application/json; charset=utf-8
Date:Fri, 19 Jul 2013 20:51:49 GMT
Expires:Mon, 01 Jan 1990 00:00:00 GMT
Pragma:no-cache
Server:Microsoft-IIS/8.0

因此,对于遇到这个问题的其他人来说,请确保将过期日期设置为这个任意日期!

1
如果您设置了no-store,则不要设置no-cache、must-revalidate、max-age和expires,因为它们与no-store相矛盾。No-store意味着表示不能被存储,其余的指令解释了管理存储表示的规则。 - Darrel Miller
1
这两个链接:http://www.i18nguy.com/markup/metatags.html 和 https://dev59.com/XnNA5IYBdhLWcg3wrf83 都表明“no-cache”确实意味着不要缓存,但“no-store”表示可以缓存但不允许归档。 - automaton
3
我建议阅读该主题的官方文档 http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-23#section-7.2.2 。 - Darrel Miller
2
IETF?真的吗?这就像让我去W3C了解“正确”的内容一样。让我们记住,这是商业领域,在商业领域,什么是正确的并不重要,重要的是什么有效。而且很明显,当前的浏览器实现并没有遵循IETF所说的“正确”方式。 - automaton
3
你提供的那个错误报告以及作者创建的第二个报告都已关闭,因为作者不理解缓存的工作原理。Chrome团队以及像squid这样的缓存代理软件开发人员都参与了IETF的工作。你提供的Stack Overflow文章仅仅是更多的例子,证明人们没有仔细阅读规范。 - Darrel Miller
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接