【发布时间】:2014-02-23 11:22:23
【问题描述】:
我一直在努力刷新对 HTTP/1.1 缓存的理解——我发现我必须每隔一段时间就做一次,因为我的大脑似乎有太多可能的组合无法可靠地记住。
我认为Expires 或max-age 缓存控制指令被浏览器用作提示,而不是铁律:如果缓存条目过时(超过其最大年龄),浏览器可以验证它。
我和一位同事为此发生了争执,他强迫我阅读 RFC,我觉得这有点苛刻,但证明他完全正确:如果我理解正确,则不允许客户使用缓存他们知道是陈旧的条目。
换句话说:如果一个文档指定了 max-age 缓存头,并且没有其他指令(例如 must-validate)影响缓存行为,并且该文档的缓存条目变得陈旧,浏览器将始终重新验证它。
这是完全清楚和合乎逻辑的,为了搁置这个论点,我开始通过让服务器提供具有以下标头的测试 JavaScript 文件来凭经验确认它:
< HTTP/1.1 200 OK
< Content-Type: application/x-javascript; charset=UTF-8
< Cache-Control: public, max-age=30
< Date: Thu, 30 Jan 2014 22:11:28 GMT
< Accept-Ranges: bytes
< Server: testServer/1.0
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
此 JavaScript 文件通过文档的 <head> 中的 <script> 元素包含在同一服务器上托管的 HTML 页面中。 HTML 页面提供以下缓存控制标头:
Cache-Control: no-cache, must-revalidate, no-store, max-age=0
加载 HTML 页面后,我点击进入另一个页面,等待 5 分钟,然后点击返回原始页面的链接,监控所有 HTTP 请求 - 从未请求过测试文件。这在 Firefox 和 Safari 的最新版本中得到了一致的复制。
这有点冗长,但我的问题的要点是:我的测试似乎表明主流浏览器不尊重 RFC,并且不会重新验证过时的缓存条目。我是否误解了 RFC?同样可能的是,我是否搞砸了我的测试,有人能证明他们错了吗?还是浏览器真的不尊重max-age 缓存指令?
【问题讨论】:
-
HTTP/1.0或HTTP/1.1?顺便说一句,我和你在一起,我不认为浏览器在缓存方面会遵守 RFC 中的必须... -
好点,谢谢。我已编辑问题以指定
HTTP/1.1。 -
如何让浏览器请求该文件,是否将其用作 html 文档中脚本标签的来源?该文档使用什么缓存标头提供服务? “导航离开并返回”是什么意思,(如何)刷新包含页面?
-
我已经更新了问题:脚本是通过
<script>标签包含的,我不刷新包含页面而是从外部链接加载它,“导航离开”意味着进入另一个页面(为了不用强行刷新就可以回到原来的那个),HTML页面提供Cache-Control: no-cache, must-revalidate, no-store, max-age=0 -
这意味着当你点击返回时,包含页面将被重新请求。你能看到这种情况吗(你指的是 html 或 js 文件的“测试文件”)吗?页面上实际使用了 JavaScript 吗?