304 状态码详解(协商缓存)
上一篇文章针对不同的状态码做了一个整顿,还说到要专门针对 304 做一个详解,于是与,今晚又来学习了。
首先说一下背景:
咱们晓得前端代码打包后须要部署到动态服务器上。客户端通过输出 url 就能看到对应的页面。从客户端到服务器发送申请到接管资源须要建设连贯、耗费宽带。
然而动态资源的更改频率往往没有那么高,于是就有一些专门的 response header 设置。通过这些设置让浏览器在获取资源文件时间接从本地硬盘或者内存获取,而不用再发送申请。这样也加重了服务器的累赘,同时还放慢了客户端的网页加载速度,用户体验好。
设置形式:
1、通过 expires(http1 时的标准,目前是向下兼容所以有的网站还在用这个):它的值是一个相对工夫的 GMT 工夫字符串。
2、cache-control 字段:该字段有几个可选值包含 no-cache、no-store、public、private 等,这些值决定了是否应用缓存以及缓存的形式。
no-cache 时,代表不应用本地缓存,客户端会向服务器发送申请,由服务器决定是否从新获取资源。
no-store 时,会残缺下载资源
public 时:示意资源能够被所有用户缓存,包含服务器
private 时示意资源只能被浏览器终端缓存
如果两者同时存在,cache-control 优先级更高一些。
当咱们发送申请让浏览器进行判断时,客户端和服务器须要一些标识来进行通信
比方 If-Modified-Since 和If-None-Match字段
这两个字段的值通过第一次申请的 response header 中的 last-modified、etag 携带过去。
示例
// response header
etag: '5c20abbd-e2e8'
last-modified: Mon, 24 Dec 2018 09:49:49 GMT
// request header 变为
if-none-matched: '5c20abbd-e2e8'
if-modified-since: Mon, 24 Dec 2018 09:49:49 GMT
浏览器没有命中强缓存并走协商缓存时就把这些值跟资源文件的信息进行比对。
如果资源没更改,返回 304,浏览器读取本地缓存。
如果资源有更改,返回 200,返回最新的资源。
至于为什么有 etag 和 last-modified 两个字段次要是解决服务器不能准确事件的问题而新增了 etag 导致的,两个判断相辅相成,具体如何决策看服务器如何解决了