为什么我的缓存设置在 chrome 中不生效
结论
在chrome浏览器中,通过前端代码来控制缓存是不可靠的,网络上搜索到的meta方法统统不可靠[5]。目前如果想解决缓存问题,只能在IIS中设置。关于如何设置的问题,详情请参考文献1,下面是文献1中重要部分的摘录与说明:
针对上图的第3点,补充说明如下(很重要,请仔细阅读):
首先必要要说明的一点是缓存本身不是问题,所有单纯的禁用缓存是不可取的。
如果静态文件(比如图片、配置文件等)更新频繁且想要立马可看(一般是开发建设时,需求功能频繁变动的情况下),建议选择immediately或after 1min以下(对服务器压力比较大,但是开发阶段由于未开放供大量用户访问,其实压力也还好);
如果是上线后,稳定运行,为了兼顾利用缓存减轻服务器压力和较短的修改响应时间,可以设置30min-1day,具体的情况需要根据【变动频繁情况】以及【客户要求的响应时间】决定。
详细解释
下面会针对上面提到的几点,以问答的形式进行详细解释,如果背后的原理感兴趣可以阅读,如果不感兴趣可以直接退出了。
如果对浏览器缓存的基本知识感兴趣可以查看文献2
为什么说在chrome浏览器中,通过前端代码来控制缓存是不可靠的
关于这个问题,其根本原因在于chrome中有算法控制资源是否缓存,已达到优化的目的,正是由于这种黑盒式的优化造成了某些情况下前端代码设置失效的问题。
补充3点引用说明:
浏览器缓存优化 ,具体参考文献2
这是浏览器的行为,前端代码控制不了
浏览器默认行为:其实就算Response Header中没有设置Cache-Control和Expires,浏览器仍然会缓存某些资源,这是浏览器的默认行为,是为了提升性能进行的优化,每个浏览器的行为可能不一致,有些浏览器甚至没有这样的优化
实际遇到的现象是chrome中未设置Cache-Control和Expires的情况下,仍然出现了200 from dist cache ,在IE中发现没有200 from dist cache。
解释:200 from cache表示使用了强缓存(本地缓存),理想状态下,在未设置Cache-Control和Expires的情况下应当不会使用强缓存。
同一静态文件在刷新时200或304不定时替换,具体参考文献3
这应该也是chrome的某种算法控制的
在没有设置Cache-Control的情况下,设置Last-Modified和ETag缓存,会出现时而200(from cache),时而304 出现的情况。
chrome 测试 刷新 和 输入URL回车 测试并不会影响200(from cache)和304 的出现。
可能的情况,是在服务器没有设置显示缓存时间的情况下,freshness_lifetime是浏览器按某种算法计算出来,这个时间并不长,所以会出现这种情况
不同静态文件在一次刷新时呈现不同的code,具体参考文献4
呈现的现象是有的静态文件被缓存了,有的没有。原因可能还是算法的问题
如果在同一标签中对同一URI的另一个请求后立即发出请求(通过单击刷新按钮,或F5之类的),Google Chrome会忽略该标头Cache-Control或Expires标头。它可能有一个算法来猜测用户真正想做什么
综上,chrome中为了提升用户体验,加入了算法来控制资源是否缓存。显然,这些算法的优先级是要高于我们的前端代码的。所以,只通过前端代码是设置缓存类型或是否缓存,是不可靠的。
补充说明 需要注意的是,当我们查阅相关资料时,会提到http的各种头部控制,控制强缓存、弱缓存等等。但是我们的代码中设置了对应的代码不起作用,这并不意味着http的理论出了问题(头部控制不起作用了)。请求头的作用仍然存在,只不过浏览器的算法会忽视这些请求头[6],即不会把对应的请求头加入到对应的请求中。
强缓存的2个标签分别是cache-control和expire,为什么代码中还经常出现Pragma
这里引用MDN的一段说明,简单的意思就是Pragma和cache-control是同一功能在不同时代的产物。
在很多地方还会看到Pragma ,它的作用可以等同于cache-control,Pragma是http1.0时的产物,这个首部的效果依赖于不同的实现,所以在“请求-响应”链中可能会有不同的效果。它用来向后兼容只支持 HTTP/1.0 协议的缓存服务器,那时候 HTTP/1.1 协议中的 Cache-Control 还没有出来
参考文献
版权声明: 本文为 InfoQ 作者【书虫】的原创文章。
原文链接:【http://xie.infoq.cn/article/70b359ab1210efb6f5b253e24】。文章转载请联系作者。
评论