场景
在前端的静态资源更新部署之后,往往会出现在浏览器端存在缓存导致展示的页面不是最新问题。
在访问一次后,第二次访问开始走浏览器强缓存,导致资源更改后不能及时更新
进行nginx配置后,走协商缓存,可以及时更新资源
解决方案
通过配置静态资源,在ngxin的location字段中配置一下if逻辑可以解决缓存的问题。
location /... {
if ($request_filename ~* .*.(?:htm|html)$) {
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
}
if ($request_filename ~* .*.(js|css|mp4|png|jpg|jpeg|woff|gif|ogg|ogv)$) {
add_header Cache-Control "no-cache, max-age=-1";
}
...
}
原理分析
浏览器的缓存策略由4个响应头控制:
ETag,Last-Modified, Expires, Cache-Control
1.其中ETag与Last-Modified用于校验文件的一致性,也就是用于判断文件是否更改过,在nginx中默认是打开的
2.Expires与Cache-Control用于配置校验的策略,其中Cache-Control的优先级更高所以我们配置这个选项即可
3.Cache-Control有多种选项可以多选如有冲突会选择更严格的选项,其中no-store是禁用缓存,no-cache是不立即使用本地缓存,是否使用要由max-age字段决定,max-age字段可以设置一个相对时间,在这段时间内浏览器直接使用本地缓存,不会走服务器。当超过这个时间,请求会访问服务器,如果文件没有改动那么直接走304打回本地,还是使用本地缓存,如果文件改动了,那就走200并返回最新的资源。设置为-1则表示不立即使用本地缓存。
4.当没有配置max-age的时候,浏览器本身会有一个默认的缓存时间,所以导致了资源不能及时更新。
相关概念解释
强缓存(无HTTP请求,无需协商)
直接读取本地缓存,无需向服务端发送请求确认,HTTP返回状态码是200(from memory cache或者from disk cache ,不同浏览器返回的信息不一致的)。
相关的 HTTP Header 有:
•Cache-Control
•Expires
协商缓存(有HTTP请求,需协商)
浏览器虽然发现了本地有该资源的缓存,但是缓存已经过期,于是向服务器询问缓存内容是否还可以使用,若服务器认为浏览器的缓存内容还可用,那么便会返回304(Not Modified)HTTP状态码,告诉浏览器读取本地缓存;如果服务器认为浏览器的缓存内容已经改变,则返回新的请求的资源。
相关的 HTTP Header 有:
•Last-Modified
•ETag
浏览器缓存模型如图:
只有强缓存与协商缓存都被击穿后才会走真正的请求,此时返回状态码200以及相应内容