谷歌浏览器不会来回重新验证 etag
Posted
技术标签:
【中文标题】谷歌浏览器不会来回重新验证 etag【英文标题】:Google Chrome does not revalidate etag on back/forth 【发布时间】:2013-04-16 21:39:10 【问题描述】:即使我发送“缓存控制:必须重新验证”,谷歌浏览器在使用浏览器中的来回按钮时也会使用本地缓存的页面。
这是原始回复的一部分:
HTTP/1.1 200 OK
cache-control: private, must-revalidate
etag: "c9239b5d4b98949f8469a05062e05bb999d7512e"
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
如果我刷新页面,我会收到“HTTP/1.1 304 Not Modified”响应,但是当我使用返回按钮时,我会收到以下响应:
Request URL:example.com
Request Method:GET
Status Code:200 OK (from cache)
我正在寻找的响应是 304 或 200 OK,有没有可能实现这个?
【问题讨论】:
【参考方案1】:“必须重新验证”指令仅在响应过时 (RFC2616, sec 14.9.4) 后应用。由于响应既不包含“Expires”标头也不包含“max-age”指令,浏览器可能会将响应视为仍然新鲜,并相应地返回缓存的副本。为了防止这种情况,您应该在 Cache-Control 标头中包含“max-age: 0”(可能还有一个包含过去日期的 Expires 标头),以便缓存的响应立即变得陈旧。或者,要防止缓存,请使用“no-cache”指令而不是“must-revalidate”。
【讨论】:
从 RFC2616 的 13.2.4 开始:“max-age 指令优先于 Expires”。你不需要两者。无论如何,这些都不会阻止浏览器在使用后退按钮导航时显示陈旧的副本。 我刚刚确认了 James 的评论,该解决方案不适用于后退按钮。【参考方案2】:no-store
缓存指令可用于指示浏览器不要将页面写入磁盘缓存。结合no-cache
这应该确保所有浏览器都会从上游而不是从磁盘获取资源。
Cache-Control: private, no-cache, no-store
【讨论】:
除非我希望浏览器在来回导航时重新验证 etag。 这将违反 RFC2616 第 13.13 节 (w3.org/Protocols/rfc2616/rfc2616-sec13.html),该节指定浏览器不应重新验证:“历史机制和缓存是不同的。特别是历史机制不应尝试显示当前的语义透明视图资源的状态。相反,历史机制旨在准确显示用户在检索资源时所看到的内容。不重新验证或获取通过后退按钮访问的过期页面的浏览器实际上是在做正确的事情 - 这不是你想要的。 只有no-store
有效,因为浏览器别无选择,它没有本地副本可显示,所以它必须在上游获取它。【参考方案3】:
使用后退和前进按钮时,防止浏览器返回页面缓存副本的关键Cache-Control
指令是no-store
。
没有其他帮助,也不需要其他任何东西。您的 Cache-Control
标头可以是:
Cache-Control: no-store
这有两个例外。
-
无论您设置什么标题(至少是我测试过的版本),Opera 和 Safari 都不会重新验证。如果您在新标签页中打开页面,该副本将是新的,但在您刷新或重新输入网址之前,原始标签页将继续显示旧版本。
Firefox 似乎在打开的第一页的缓存中存在错误(即没有返回按钮时)。当您来回导航时,该页面的所有后续实例都会刷新,但是一旦您一直备份到最顶部的页面,它通常仍会显示其初始过时副本。
最后,我应该指出,一般不建议使用该指令,因为它显然会对带宽使用产生重大影响。浏览器甚至无法利用Etags
来获得304 Not Modified
响应,因为在收到304
响应的情况下,它没有存储的副本可供使用。
【讨论】:
所以基本上如果你想让后退/前进按钮工作你不能利用 etags? madhatted.com/2013/6/16/you-do-not-understand-browser-history 包含对这种情况的有趣讨论。 100 分。 “浏览器甚至无法利用Etags
”这就是我正在寻找的答案,为什么 Etags 不起作用。
实际上,chrome 以某种方式在所有与缓存相关的标头之上应用了算法行为,因此 ETag 可能不起作用并返回 304【参考方案4】:
缓存控制未设置,强制浏览器使用default
。 (在此处阅读有关缓存选项的更多信息:https://developer.mozilla.org/en-US/docs/Web/API/Request/cache)
为了重新评估缓存,您必须将服务器配置为发送Cache-Control: no-cache
header;或通过设置Request.cache = 'no-cache'
option 浏览器/客户端。仅此选项就足以正确使用 ETag。
【讨论】:
以上是关于谷歌浏览器不会来回重新验证 etag的主要内容,如果未能解决你的问题,请参考以下文章