HTTP缓存策略

HTTP缓存策略包括两种:强制缓存、协商缓存。

强制缓存

图片 1.png

Expires

服务器responseheader带上这个字段,然后在这个时间前,客户端浏览器都不会再发起请求,而是直接用缓存资源。

Expires: Wed, 21 Oct 2000 07:28:00 GMT
Cache-Control

常用属性包括:

  • max-age:缓存最大过期时间
  • no-cache:可以在客户端存储资源,每次都必须去服务端做新鲜度校验,来决定从服务端获取新的资源(200)还是使用客户端缓存(304)
  • no-store:永远都不要在客户端存储资源,永远都去原始服务器去获取资源
Cache-Control: max-age=20000

这表示当前资源在20000秒内都不用再请求了,直接使用缓存。

协商缓存

Last-Modified 和 If-Modified-Since

Last-ModifiedIf-Modified-Since是配套使用的,**Last-Modified是放到responseheader里面的**,可能长这样:

Last-Modified: Wed, 21 Oct 2000 07:28:00 GMT 

而客户端浏览器在使用时,应该将配套的If-Modified-Since放到**requestheader里面**,长这样:

If-Modified-Since: Wed, 21 Oct 2000 07:28:00 GMT 

服务端拿到这个头后,会跟当前版本的修改时间进行比较:

  1. 当前版本的修改时间比这个晚,也就是这个时间后又改过了,返回200和新的内容
  2. 当前版本的修改时间和这个一样,也就是没有更新,返回304,不返回内容,只返回头,客户端直接使用缓存
Etag 和 Last-Modified

EtagLast-Modified是配套使用的,**Etag是放到responseheader里面的**,可能长这样:

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

客户端拿到后会将这个ETag和返回值一起存下来,等下次请求时,使用配套的If-None-Match,将这个放到requestheader里面,可能长这样:

If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

然后服务端拿到请求里面的If-None-Match跟当前版本的ETag比较下:

  1. 如果是一样的话,直接返回304,语义为Not Modified,不返回内容(body),只返回header,告诉浏览器直接用缓存。
  2. 如果不一样的话,返回200和最新的内容

综述

图片 5.png

缓存优先级

  • Cache-Control的优先级比Expire

  • ETag的优先级比Last-Modified

  • 强制缓存和协商缓存优先级:先判断强制缓存,如果强制缓存生效,直接使用缓存;如果强制缓存失效,再发请求跟服务器协商,看要不要使用缓存

三种刷新操作对 http 缓存的影响

  • 正常操作:地址栏输入 url,跳转链接,前进后退等。
  • 手动刷新:f5,点击刷新按钮,右键菜单刷新。
  • 强制刷新:ctrl + f5,shift+command+r。

正常操作:强制缓存有效,协商缓存有效。 手动刷新:强制缓存失效,协商缓存有效。 强制刷新:强制缓存失效,协商缓存失效。

参考资料:

https://segmentfault.com/a/1190000038562294

https://juejin.cn/post/7061588533214969892#heading-52