这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
上文我们说到,http有两种,一种是强缓存,另外一种就是我们这篇笔记所说的协商缓存
控制强缓存一般是通过cache-control或者expires,它们都是响应头。而协商缓存中除了响应头还有请求头
协商缓存(服务器根据某标识来判断缓存是否过期)
浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给客户端,浏览器将二者备份至缓存数据库中。
再次请求数据时,客户端将备份的缓存标识发送给服务器,服务器根据缓存标识进行比较,成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。 简单一点就是:强缓存失败后就会进行协商缓存:服务器会根据缓存标识来进行比较,如果成功了,就返回304状态码,通知客户端比较成功,可以使用缓存数据。比较失败后,服务器就会重新返回数据。
与协商缓存有关的请求/响应头
- last-modified:GMT格式,代表服务器资源的最后修改时间。第一次请求服务器,服务器可以通过这个响应头来设置协商缓存
- if-modified-since:GMT格式,代表本地资源的最后修改时间,第二次请求服务器时,就会带上这个请求头(服务器会根据这个请求头跟服务器的资源最后修改时间比较,如果前者两个相等,就会返回304,让浏览器去拿缓存数据。否则就返回200和最新的资源,并且重新进行缓存)
上述实现协商缓存有一定的缺陷
- 使用last-modified/if-modified-since只能精确到秒,如果服务器文件修改得很快,文件的GMT时间没有变就不会返回最新的资源
- 内容未被修改,但修改文件,服务器GMT时间会改变。等下次浏览器发请求过来,服务器就会判断文件已被更新,就返回200和最新的资源。
实现更好的协商缓存
- ETag:标识字符串。代表这个字符串只有文件内容真正被修改的时候才会改变
- if-none-match:标识字符串。(服务端收到该字段就会跟它对比,如果前者两个相等,就会返回304,让浏览器去拿缓存数据。否则就返回200和最新的资源,并且重新进行缓存)
注意:上一篇笔记忘记说了,如果expires与cache-control都存在的话,以cache-control主,Etag和last-modified都存在,以Etag为主