如何解决静态资源的缓存问题
最近写了一个面向大众的导航站,初期一直在修改js和css,由于是托管到coding上的,浏览器的缓存问题是真的要命,自己倒是知道清理缓存,但其他人不知道啊,所以在网上查了下解决办法,特来总结一下
前言
浏览器的缓存机制其实是一个很好的优化机制,可以避免重复请求相同的资源,减轻服务器的压力,也可以加快用户的二次读取。但凡事都有优缺点,缓存的存在会导致css,js或者其他静态资源不能及时更新。有时修改了html,html一般不会读取缓存,但css和js读取了缓存,就会出现一些莫名其妙的问题,而到了用户那边,则会一脸懵逼。
浏览器的缓存原理
这个我也不太懂,就知道分为强制缓存和协商缓存。当二次打开网页时,浏览器会先对缓存发起http请求,只要请求的资源存在缓存并且该资源的请求头
expires
和
cache-control
中存在缓存的标志,那就默认读取缓存,如果缓存失效但缓存依然存在,这时有会对服务器发出http请求,通过
last-modified
和
etag
两个请求头验证是否存在协商缓存,存在协商缓存就让浏览器照样读取缓存。
当然,如果你资源已经不存在了或者明确禁止缓存,那浏览器也不可能使用缓存,这也是解决缓存问题的办法
强制缓存
强制缓存两个请求头,
expires
和
cache-control
expires
不怎么用,是http1.0提出的一个表示资源过期时间的header 而
cache-control
出现于 HTTP / 1.1,优先级高于 Expires,同样也可以表示资源过期时间 当然
cache-control
并没有这么简单,有很多值,但常用的基本就是下面5个值 - public:所有内容都将被缓存(客户端和代理服务器都可缓存) - private:所有内容只有客户端可以缓存,Cache-Control的默认取值 - no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定 - no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存 - max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
强制缓存是否生效,可以查看控制台的network选项,下面的size属性,一般就是
from memory cache
或者
from disk cache
,一个是从内存中加载缓存,一个是硬盘中加载缓存,区别就是内存要快些,一般先是读取硬盘中的缓存,要是你刷新一下,就从内存中读取,不然刷新的时候怎么那么快
协商缓存
当强制缓存失败,浏览器就请求服务器,如果服务器觉得用缓存没问题,资源又没有更新,那么,即使缓存设了到期时间,浏览器依然会读取,此时服务器返回304,如果资源更新了,就从服务器请求更新,返回200。如何判断资源是否更新,就是靠
last-modified
和
etag
两个请求头,这里我就不多讲了
但是要注意,强制缓存要优先于协商缓存,所以嘛,就算你更新了,浏览器依旧会读取缓存 ,这也就是问题的由来,解决办法很简单,要么直接禁用缓存,告诉浏览器不准使用我的缓存,每次都从服务器加载。要么就是把文件名字改了,缓存名字对不上也就不会读取缓存了
解决办法
知乎上有个回答说的挺好
浏览器是好人(meta),浏览器有点坏(版本号),浏览器老子看你不爽了,我要“欺骗你”(md5)
meta缓存头设置为禁止缓存
在html的head标签中加入下面内容,就可以禁止浏览器读取缓存
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />