浏览器缓存机制有四个方面,它们按照获取资源时请求的优先级依次排列如下:
- service Worker
- 通过fetch监听网络请求
- 实现离线缓存、消息推送和网络代理等功能,必须以 https 协议为前提
- Memory Cache
- 内存缓存
- 浏览器自行判断,内存有限,一般存储较小的文件
- 浏览器窗口关闭,内存也清空了,下次请求根据优先级走dist cache
- dist cache
- 磁盘缓存-http缓存
- push cache--https支持
http缓存
-
HTTP缓存有以下几种方式
- 强缓存
- expires:Thu, 10 Nov 2017 08:45:11 GMT
- http1.0中提供缓存字段,是一个绝对时间,由于客户端时间可改,所以基本不使用
- catch-control:public,private,no-cache,no-store,max-age=时间毫秒,s-maxage=时间毫秒,must-revalidate等
- http1.1中增加缓存字段,作为expires的升级版,是一个绝对时间,不会受客户端时间修改影响,但是为了兼容全部浏览器建议两者都写
- public:可以在客户端和代理服务缓存
- private:只能在客户端缓存
- no-cache:客户端允许缓存,不走强缓存,走对比缓存
- no-store:不允许缓存,直接请求根服务资源
- max-age:客户端过期时间,max-age=0,浏览器判断时间过去,需要继续去服务对比缓存
- must-revalidate:如果客户端缓存对比结果过期,浏览器必须向服务器验证资源是否还有效,设置maxage=0,must-revalidate等价于no-cache
- s-maxage:代理服务缓存过期时间,只在catch-control:public有效
- 客户端也可以设置catch-control字段:no-store,no-cache等
- expires:Thu, 10 Nov 2017 08:45:11 GMT
- 协商缓存(又称对比缓存)
- Etag:
- 服务响应头字段Etag/请求头字段if-None-Match
- last-Modified:
- 服务响应头字段last-Modified/请求头字段if-Motified-Since
- Etag:
- 强缓存
-
缓存优先级
- 强缓存优先级高于协商缓存
- 强缓存中如果cache-control和expires同时存在,并且两者都有设置过期时间,就算expires没有过期,也只判断cache-control
- 协商缓存中如果Etag和Last-Modified同时存在,则对比etag,其次对比last-Modified
-
缓存流程
浏览器对某资源发起请求,判断本地是否有缓存响应头信息,如果没有会缓存响应头的信息,如果有择判断是否命中强缓存,如果命中强缓存,则从缓存获取资源,如果没有则判断是否命中协商缓存,命中协商缓存则向资源服务器发送携带协商字段()的请求,有服务器判断资源是否更改,如果无更改则返回304状态码,解析缓存获取资源,如果有更改则返回200状态码并返回新的资源。
-
协商缓存说明 如果存在协商缓存,会在请求头信息中携带etag和last-Modifie对应的if-None_match和if-modified-Since信息发给服务器,并等待响应。
-
特别说明(摘录)
针对我们当前的项目,由于css和js在打包时加了md5值,建议直接使用强缓存,并且expires和cache-control同时使用,建议设置时长为7天较为妥当。图片文件由于没有加md5值,建议采用对比缓存,html文件也建议采用对比缓存。
ps: 当我们不设置cache-control,只设置对比缓存,在不同浏览器下会有不同的表现。chrome会直接从本地缓存获取,其他会请求服务器返回304.这时候有两种方式让他们的响应一致。
- 设置cache-control: public, max-age=0;记住,这里的public是关键。因为默认值是private,表示其他代理都不要缓存,只有服务器缓存,而max-age又为0,所以每次都会发起200的请求。设置public的意思就是允许其他各级代理缓存资源,因此如果资源没改变会返回304。
- 直接设置max-age=1000。即是一秒之后内容过期,目的是触发浏览器缓存。也能达到想要304的效果。
-
推荐地址