客户端缓存
客户端缓存是指客户端在本地保存用户最近请求过的数据,当用户再次访问时,客户端直接从本地磁盘加载数据。其可分为强缓存(本地缓存)和弱缓存(协商缓存)
强缓存:用户非首次访问资源与使用强缓存,那么在过期时间内不会从向服务端发起请求,而是直接从本地缓存中获取(不管资源是否变化)
协商缓存:用户非首次访问资源与使用协商缓存,需要向服务端发起请求,判断资源的最后修改时间或者资源的唯一标识是否修改,若未修改,返回状态码304,从缓存中获取;否则重新发起请求,并更新客户端缓存。
1、强缓存(强制缓存)
强缓存利用的是http响应头中的expires和Cache-Control
1-1 expires
这是HTTP/1.0的字段,是一个绝对时间(当前时间+缓存时间),如expires: Sun, 21 Nov 2032 23:43:27 GMT
设置这个字段后,在未过期之前不需要从服务端请求数据
缺点:由于是绝对时间,用户可修改客户端本地的时间,导致缓存失效;同时,时差或者误差也会导致客户端与服务端的时间不一致,导致缓存失效
1-2 Cache-Control
这是HTTP/1.1中新增的字段,表示资源缓存的最大有效时间,如cache-control: public, max-age=31536000
其包含一些常用的值
- private:仅客户端可以缓存(默认值);
- public:客户端和代理服务端都可以缓存;
- max-age=xxx:最大有效时间(单位秒);
- must-revalidate:如果超过了 max-age 的时间,客户端必须向服务端发送请求,验证资源是否还有效。
- no-cache:表示客户端可以缓存资源,但每次使用前都需要验证缓存资源的有效性,相当于 max-age=0,must-revalidate;
- no-store:不强缓存,也不协商缓存
对比:自HTTP/1.1开始, expires逐渐被Cache-Control取代。Cache-Control是一个相对时间,即使客户端时间发生改变,相对时间也不会随之改变,这样可以保证服务端与客户端的时间的一致性,同时,Cache-Control的可选择的配置项
强缓存来源可分成内存缓存和磁盘缓存 from mermory cache 是页面刷新的时候内存缓存中获取 from disk cache 是关闭Tab时从磁盘缓存中获取
例如非首次访问百度首页时,在控制面板中可以看到大部分资源返回状态码是 200 (from memory cache 内存缓存),其中Response Headers 返回了cache-control: max-age=2592000,这说明该资源走的是强缓存策略
2、协商缓存(对比缓存)
当强缓存失效,则使用协商缓存,由服务端决定缓存是否失效。协商缓存包含两组字段
2-1 Last-Modified & If-Modified-Since
Last-Modified表示的是文件的最后修改时间
交互流程
- 客户端发起GET请求
- 服务端接收、处理请求,返回响应头再,包含Last-Modified字段,客户端存储资源与该字段
- 当再次请求资源时,将缓存的 Last-Modified 的值写入到请求头的 If-Modified-Since 字段
- 服务端将If-Modified-Since的值与Last-Modified相比较,若相等,数据未修改,返回304状态码;否则,响应200,返回最新的数据和Last-Modified
2-2 Etag & If-None-Match
Etag存储的是文件的特殊标识,可以保证每个资源都是唯一的,资源变化会导致Etag变化
ETag的格式为:Etag= [ weak ] opaque-tag
| 值 | 类型 |
|---|---|
| Etag="61a48a78-aba" | 强校验 |
| Etag=W/"61a48a78-aba" | 弱校验(W大小写敏感) |
Etag & If-None-Match的交互流程与Last-Modified & If-Modified-Since的交互流程一样 在交互上,Etag 对应 Last-Modified,If-None-Match 对应 If-Modified-Since
Etag主要为了解决 Last-Modified 无法解决的一些问题: 1、因为 Last-Modified 能检查到的粒度是秒级的,所以当服务端的更新资源速度是秒以下的,会导致获取不到最新的数据 2、如果文件是通过服务端动态生成的或者周期性更改,内容不变,仅仅是修改时间,这时候就起不到缓存的效果; 3、某些服务器不能精确的得到文件的最后修改时间;
Etag 的优先级高于 Last-Modified,大部分web服务器会默认开启协商缓存,同时开启【 Last-Modified & If-Modified-Since】和【Etag & If-None-Match】,确保缓存的可靠性。
例如非首次访问百度首页时,在控制面板中可以看到部分资源返回状态码是 304,其中Request Headers 和 Response Headers 出现了 ETag/If-None-Match、Last-Modified/If-Modified-Since字段,这说明该资源走的是协商缓存策略。
3、缓存位置
使用强缓存时,可以看到缓存的来源有from memory cache(内存缓存)与disk cache(磁盘缓存),指的就是缓存所在的位置。请求一个资源,会按照优先级依次查找缓存:
Service Worker -> Memory Cache -> Disk Cache -> Push Cache
200 from memory cache
表示不向服务器发起请求,从内存缓存获取数据。从内存中获取数据,读取速度较快,但关闭tab后,资源随之被销毁。一般来说,内存缓存存储较小的文件
200 from disk cache
表示不向服务器发起请求,从磁盘缓存获取数据。与内存相比,硬盘的读取速度相对较慢,但硬盘缓存持续的时间更长,关闭tab之后,缓存的资源仍然存在。同时,磁盘的容量较大,一般用于存储大文件