在 HTTP cache 中讲解了 HTTP 缓存相关的知识,我们知道了:
Cache-Control
用来控制强缓存(code:200, from memory/disk),Last-Modified/If-Modified-Since 和 Etag/If-None-Match
用来控制协商缓存,决定是(code:304,Not Modified),还是 (code:200, from server)
浏览器的行为(back/forward/refresh
)又和 HTTP 缓存怎么互相配合的?
在 single-page app 中的,点击超链接跳转其他的路由,然后点击浏览器的回退和点击超链接回退又有什么区别呢?回来的页面会刷新吗?
实验
三个获取随机 字符串的请求 no-cache
,no-store
,,Header 分别设计为:
- /api/test/no-cache:
Cache-Control: must-revalidate, no-cache, private
Pragma: no-cache
Etag: "((the hex value))"
- /api/test/no-store:
Cache-Control: must-revalidate, no-store, no-cache, private
Pragma: no-store, no-cache
Etag: "((the hex value))"
- /api/test/no-cache?test=Math.random():
Cache-Control: must-revalidate, no-cache, private
Pragma: no-cache
Etag: "((the hex value))"
最后一个用来破坏缓存,每次都会请求最新的数据
Chrome
浏览器 back
清空缓存:
点击第一个超链接跳转到同源的 other page, 然后点击浏览器的back,回到主页:
得出结论:
- home page 和 no-cache 接口都被缓存
- no-store 接口不被缓存,重新触发了请求
点击页面超链接回退
清空缓存:
点击第一个超链接跳转到同源的 other page, 然后点击other page 上的超链接,回到主页:
得出结论:
- home page 和 no-cache 接口不被缓存,重新触发了请求
- no-store 接口不被缓存,重新触发了请求
刷新浏览器
清空缓存:
点击浏览器刷新按钮:
得出结论:
- home page 和 no-cache 接口不被缓存,重新触发了请求
- no-store 接口不被缓存,重新触发了请求
Safari
浏览器 back
清空缓存:
点击第一个超链接跳转到同源的 other page, 然后点击浏览器的back,回到主页:
得出结论:
- home page 没有被缓存,触发了新请求,但是所有的接口的都没有触发重新请求
- no-cache 接口被缓存
- no-store 接口被缓存
点击页面超链接回退
清空缓存:
点击第一个超链接跳转到同源的 other page, 然后点击other page 上的超链接,回到主页:
得出结论:
- home page 和 no-cache 接口不被缓存,重新触发了请求
- no-store 接口不被缓存,重新触发了请求
刷新浏览器
清空缓存:
点击浏览器刷新按钮:
得出结论:
- home page 和 no-cache 接口不被缓存,重新触发了请求
- no-store 接口不被缓存,重新触发了请求
结论
- 可能每种浏览器实现的方式都不一样
- 但是对于HTML文件的处理,倒是很相似,刷新浏览器还是点击超链接回退,都是会主动请求的(哪怕已经设置了 Cache-Control:max-age:60)
为什么 HTML 文件 都不会使用缓存呢?因为客户端也可以使用
Cache-Control:max-age:0
,来强化或者放松对过期时间的限制,有些应用程序对文档的新鲜度要求很高,比如人工刷新按钮,对这些应用程序而言客户端(浏览器会自动放弃缓存从浏览器读取),可以看下 HTML 文件的Request Header Cache-Control
,做验证