cor*_*ore 56 etag caching http http-headers
浏览器何时不向服务器请求文件?
换句话说,我有一个JavaScript文件正在服务.其HTTP响应报头具有一个ETag
,Cache-Control: public
和Expires: Tue, 19 Jan 2038 03:14:07 GMT
.
304
浏览器缓存已准备好后服务器返回a .
我的问题是,为什么浏览器甚至检查服务器并首先获得一个304
?我不希望浏览器询问是否有新版本 - 它应该直接从浏览器缓存加载而不检查服务脚本的服务器的修改.
HTTP响应头的哪些组合实现了这一点?
Mar*_*ery 90
首先,相关的HTTP规范是RFC 7234.如果你看一下规范,你会发现两件事:
其次,你最终没有做错任何事.浏览器可以自由缓存响应,并根据您返回的标头使用这些缓存的响应.关键点在第4节,其中注意到服务缓存响应的条件之一是响应是:
新鲜的(见4.2节),或
允许陈旧(见第4.2.4节),或
成功验证(参见第4.3节).
由于你正在吐出一个Expires
远在未来的标题,并且未来还没有达到这一点,因此响应是"新鲜的",因此不需要重新验证.所以你正在做的事情,规范建议你应该在你的最后.(虽然使用Cache-Control: max-age=foo
是一种比使用Expires:
标头更现代的设置缓存到期时间的方法.)
因此,如果您想要更改浏览器的缓存行为,那么您就不走运了.
但是,事情可能没有你想象的那么糟糕.你可能只看到一个请求和304,因为你在测试时刷新了浏览器中的页面.浏览器根据触发请求的方式不同地处理缓存的资源.
我运行了一个简单的测试,其中我创建了一个HTML页面,其中包含<script>
指向JS文件的<img>
标记,指向图像的<link>
标记以及指向CSS样式表的标记.所有这些文件都托管在配置为以下服务的Apache服务器上:
Cache-Control: max-age=172800
头当然,所有资源都在首页加载时提供200个代码.此后,使用默认设置在Chrome或Firefox中进行测试,我观察到:
此页面表明Internet Explorer具有相同的行为:
在许多情况下,Internet Explorer需要检查缓存条目是否有效:
- 缓存条目没有到期日期,并且首次在浏览器会话中访问内容
- 缓存条目具有到期日期但已过期
- 用户通过单击"刷新"按钮或按F5请求页面更新
换句话说,如果用户明确刷新页面,通常只会看到这些重新验证请求.除非您对浏览器缓存的行为有一些非常特殊的要求,否则这种行为似乎非常合理.
谷歌和Mozilla都有一些关于HTTP缓存的文档(我在MSDN或Apple Developers网站上找不到任何相同的东西),但都没有暗示是否存在任何特定于供应商的缓存头,可用于修改浏览器使用的规则选择何时重新验证.你想做什么根本不可能.
如果您确实需要更多地控制此行为,您可以查看HTML5应用程序缓存或使用HTML5本地存储滚动您自己的缓存逻辑,就像basket.js一样.