首先,HTTP缓存分为强缓存和协商缓存。
强缓存不需要和服务器沟通,当请求发出时,浏览器会看Expires和Cache-control有没有,有的话命中缓存,返回状态码200,从缓存中获取。
协商缓存会和服务器沟通,看资源有没有没改动。没有改动,返回状态码304,资源会被服务器重定向到浏览器缓存中。
强缓存
与强缓存相关的字段有Expires和Cache-control,由于Expires是http1.0,Cache-control是http1.1的所以Cache-control的优先级高。
Expires
Expires是存储的时间戳,这就要求服务器和本地浏览器时间要统一。
Cache-control
Cache-control里面有如下字段:
- public 表示任何能被任何对象进行缓存
- private 仅表示能被客服端缓存
- no-cache 表示直接进入协商缓存
- no-store 表示不进行缓存
- max-age 设置缓存的最大周期,单位为s,超过这个时间会被认为过期
- s-maxage 覆盖max-age或者Expires头。如果s-maxage未过期,则向代理服务器请求其缓存内容。
- s-maxage仅在代理服务器中生效,客户端只需要考虑max-age。
协商缓存
协商缓存机制下,浏览器需要向服务器去询问缓存的相关信息,进而判断是重新发起请求、下载完整的响应,还是从本地获取缓存的资源。
Last-Modified & If-Modified-Since
Last-modified 设置在相应头中 是一个时间戳
if-modified-since 设置在请求头中 并且只能用在GET或HEAD请求中
解决上面服务器没有正确感知文件变化的问题
Etag & If-None-Match
Etag 响应头
If-None-Match 请求头
Etag 的生成过程需要服务器额外付出开销,会影响服务端的性能,这是它的弊端
设置一个可靠的缓存规则
如果资源不可复用,设置 cache-control:no-store
如果资源可以复用,考虑每次是否要向服务器进行缓存确认,如果需要就设置 cache-control:no-cache 走协商缓存。
如果不需要每次都向服务器确认,考虑资源是否可以被代理服务器缓存,根据其结果决定是设置为private还是public;
接下来考虑资源的过期时间,设置对应的max-age;
最后,配置协商缓存需要用到的Etag、Last-Modified等参数。
参考大佬:一文彻底掌握HTTP缓存