macOS Safari缓存响应,尽管头部指定不缓存

11
服务器对 GET 请求的响应包含以下标头:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Pragma: no-cache
Date: Thu, 08 Feb 2018 19:16:26 GMT
Cache-Control: no-cache, no-store, must-revalidate
Server: Microsoft-IIS/10.0
Content-Length: 801
Expires: -1
Content-Encoding: deflate
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 5.2

现在,4秒钟后,浏览器(macOS Safari 11.0.3)发起了相同的请求。开发者控制台显示响应是从缓存中提供的。我不明白Safari为什么会缓存响应:

  • Expires是无效的值,响应不应该被缓存
  • Cache-Control: no-cache,响应不应该被缓存
  • Cache-Control: no-store,响应不应该被缓存
  • Cache-Control: must-revalidate,响应至少应该被验证,但服务器日志中没有这样的请求
  • Pragma: no-cache,响应不应该被缓存

因此,尽管所有的头信息都明确指出响应是否应该被缓存,Safari还是选择将响应缓存下来。为什么呢?

为了完整起见,请求的内容如下:

GET (...) HTTP/1.1
Host: (...)
Referer: (...)
Accept: application/json, text/javascript, */*; q=0.01
Connection: keep-alive
Accept-Encoding: br, gzip, deflate
Accept-Language: en-us
DNT: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/604.5.6 (KHTML, like Gecko) Version/11.0.3 Safari/604.5.6
Cookie: (...)
X-Requested-With: XMLHttpRequest

我刚刚发现在网页审查器中,“已缓存:”Yes (disk)”并不代表该响应是从缓存还是服务器检索到的。有些请求显示为“已缓存:Yes (disk)”,但它们也同时出现在服务器日志中。



1
我发现了一个关于 Webkit 的错误报告,可能可以解释这个问题;https://bugs.webkit.org/show_bug.cgi?id=170714。甚至可能是这个来自 2011 年的错误报告:https://bugs.webkit.org/show_bug.cgi?id=62250。 - Bouke
1
可能与本地主机有关的相关问题:https://dev59.com/FKXja4cB1Zd3GeqPUKFL。 - Bouke
这可能是Safari的一个bug(或特性)-有很多类似的问题。作为解决方法,您可以像这里描述的那样在URL中使用随机参数https://dev59.com/fWkw5IYBdhLWcg3wXZX8。还请查看此SO讨论:https://dev59.com/FGcs5IYBdhLWcg3w433H - SergeyLebedev
你看过这篇帖子吗?https://dev59.com/03VD5IYBdhLWcg3wNY1Z?answertab=active#tab-top - Simon Franzen
你在测试之前清空了缓存,对吧?(没有旧的缓存版本)...我在Safari中也看到过类似的奇怪现象。 - user1133275
我刚发现“Cached: Yes (disk)”仍然(可能)会命中服务器。所以我不确定该列的含义。它是否与“必须重新验证”有关,服务器请求正在重新验证?那么,在我的 Ajax 调用中,我获得了什么响应呢?我想这将是重新验证的(更新的)响应? - Bouke
1个回答

14

3
通过这条评论,你为我送来了一个周五的夜晚,对此我表示“感谢”。 - Vivek Chandra
1
谢谢,@SamuelHapak - 我一直在与Safari的过度缓存(似乎比其他所有浏览器都更过度)搏斗,尝试各种变化的 Cache-Control: 头部(no-store, max-age=0, must-revalidate 等),但是,在我阅读了您上面的答案之前,我不知道 Vary: 头部和 Vary: * 的强大作用,可以覆盖所有其他客户端假设,并坚持要求从源服务器获取所请求的资源。 - Rounin
2
有人知道是哪个特定的头部值(对于 Vary)实际上使 Safari 不缓存页面吗?我使用来托管我的应用程序的服务不允许我出于任何原因执行 Vary: * - ffxsam
这解决了我在我的CCTV项目中针对macOS和iOS Safari的缓存问题。我的具体用例是使用HTML视频元素,并将海报设置为动态生成的JPEG的URL,然后加载实时流分段MP4。谢谢。 - kevinGodell

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