在Ajax 缓存: 两个重要的事实文章中, 作者指出:
在IE中,即使你按强制刷新(Ctrl+F5),在内容过期之前,Ajax也不会更新。确保更新的唯一方法是从缓存中删除此记录。
我发现这虽然很难让人相信,但这确是事实。如果碰到刷新键(F5),IE浏览器将重新请求在网页中的除XMLHttpRequest以外所有未过期 的资源。在测试期间,这肯定会为开发造成混乱,但我想知道是否还有其他问题。其他主流浏览器的行为是什么?如果内容已经过期或者没有Expires头的行 为是什么?增加Cache-Control: max-age 头有什么效果?
因此我创建了这个Ajax 缓存测试页面.
这个测试页面包含了一个图片,一个外部脚本文件和一个XMLHttpRequest。过期日期取决于我们选择的链接。
- Expires in the Past 包含了一个已过期30天的Expires 响应头, 一个Cache-Control: max-age=0 响应头
- no Expires没有返回任何Expires 或 Cache-Control 响应头
- Expires in the Future 包含一个在未来30天才过期的Expires 响应头, 一个Cache-Control :max-age=2592000 响应头.
测试很简单: 点击一下链接 (比如, Expires in the Past), 等待页面加载完毕,然后按F5。表1展示了在主流浏览器下的测试结果。结果记录了Ajax请求是否重新请求还是从缓存读取,如果重新请求HTTP状态码是什么。
表1 当Ajax被缓存,按F5的结果 | |||
Past Expires | No Expires | Future Expires | |
---|---|---|---|
Chrome 2 | 304 | 304 | 304 |
Firefox 3.5 | 304 | 304 | 304 |
IE 7 | 304 | cache | cache |
IE 8 | 304 | cache | cache |
Opera 10 | 304 | cache | 304 |
Safari 4 | 200 | 200 | 200 |
下面是我对按F5键的总结:
- 所有浏览器均重新请求图片和脚本。(这样做是有道理的)
- 所有浏览器均重新请求ajax,如果已经过期。 (这样做是有道理的 - 浏览器已经知道了缓存的Ajax已经失效)
- 唯一不同的行为是当Ajax没有设置Expires缓存头或缓存未到期时. 即使按Ctrl+F5,IE 7和8 均不 重新请求Ajax,不管没有Expires头或没有过期。 当没有Expires头时,Opera 10 不 重新请求Ajax 。(我没有找到在Opera下强制刷新的功能)
- 所有情况下,Opera 10 和 Safari 4 重新请求favicon.ico(浪费)
- 所有情况下,Safari 4 均没有发送If-Modified-Since头,导致产生HTTP 200状态码,对于图片和脚本也是一样(这是浪费并且背离了其它浏览器的行为)
结论
下面是我对页面开发人员和浏览器厂商的建议:
- 开发人员需要设置一个已过期或未过期的Expires,避免出现未指定Expires时含混不清和怪异的行为
- 如果Ajax不应 被缓存,开发人员应该设置一个已过期的过期日期
- 如果Ajax应该 被缓存,开发人员应该设置一个未过期的过期日期。当在IE 7和8下面测试时,开发人员应该记得测试重新加载(F5)时清空缓存
- 当按F5时,IE 应该重新请求Ajax
- 当按F5时,Opera 和 Safari 应该不再加载favicon.ico
- 当按F5时,Safari应该发送If-Modified-Since头