静态资源更新但是有缓存?速进我有办法解决

566 阅读2分钟

场景

在前端的静态资源更新部署之后,往往会出现在浏览器端存在缓存导致展示的页面不是最新问题。

在访问一次后,第二次访问开始走浏览器强缓存,导致资源更改后不能及时更新





进行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以及相应内容