1. 基本认知
Web 服务缓存 ⼤致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 服务器缓存)、浏览器缓存。
浏览器缓存 也包含很多内容: HTTP 缓存、indexDB、cookie、localstorage 等等。 这⾥我们只讨论 HTTP 缓存相关内容 。
http缓存分为:强制缓存和协商缓存两种
从字面意思我们可以很直观的看到它们的差别:
- 强缓存即强制直接使用缓存。
- 协商缓存就得和服务器协商确认下这个缓存能不能用。
强缓存
强缓存不会向服务器发送请求,直接从缓存中读取资源,在 chrome 控制台的 network 选项中可以看到该请求返回 200 的状态码,并且size显示from disk cache或from memory cache;
相关Header:
- Expires : response header里的过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存(Cookie失效日期,是一个时间段)。
- Cache-Control: 当值设为max-age=15552000时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。除3600s可以查看还有多少小时过期(相对时间,是一个时间点)
区别:Expires 是http1.0的产物,Cache-Control是http1.1的产物
两者同时存在的话,Cache-Control优先级高于Expires
Expires其实是过时的产物,现阶段它的存在只是一种兼容性的写法
- Expires
- Cache-Control
协商缓存
1、若未命中强缓存(强缓存过期了),则浏览器会将请求发送⾄服务器。
2、服务器根据http头信息中的 Last-Modify/If-Modify-Since 或 Etag/If-None-Match 来判断是否命中协商缓存。
3、如果命中,则http返回码为304 (你本地之前加载的资源是有效的),浏览器从缓存中加载资源。
4、由于对⽐的是服务端的修改时间,所以就算客户端与服务端时间差距, 也不会有问题
5、但是有时候通过最后修改时间来判断资源是否修改还是不太准确(资源变化了最后修改时间也可以⼀致)。⽐如: Last-Modify/If-Modify-Since最后修改只能精确到秒级, ⼀秒进⾏了多次修改, 就不⾏了, 于是出现了ETag/If-None-Match。
6、与Last-Modify/If-Modify-Since (最后修改时间)不同的是,Etag/If-None-Match返回的是⼀个校验码(ETag: entitytag),ETag可以保证每⼀个资源是唯⼀的,资源变化都会导致ETag变化
1.last-modified
2.ETag
- ETag⽣成靠以下⼏种因⼦
-
⽂件的i-node编号,是Linux/Unix⽤来识别⽂件的编号。
-
⽂件最后修改时间
-
⽂件⼤⼩**
Etag的出现主要是为了解决⼏个Last-Modified⽐较难解决的问题:
- Last-Modified标注的最后修改只能精确到秒级; 如果某些⽂件在1秒钟以内,被修改多次的话,它将不能准确标注⽂件的修改时间 有可能存在服务器没有准确获取⽂件修改时间,或者与代理服务器时间不⼀致等情形
- 有可能存在服务器没有准确获取⽂件修改时间,或者与代理服务器时间不⼀致等情形;
Etag是服务器⾃动⽣成或者由开发者⽣成的对应资源在服务器端的唯⼀标识符,能够更加 准确的控制缓存。 不会仅仅只根据最后的修改时间判断是否进⾏使⽤缓存 Last-Modified与ETag是可以⼀起使⽤的,服务器会优先验证ETag,⼀致的情况下,才会继续⽐对Last-Modified, 最后才决定是否返回304。
成功 2XX
重定向(3XX)
因为post请求, 是⾮幂等的, 从302中, 细化出了 303 和 307 简⽽⾔之:
- 301 302 307 都是重定向
- 304 协商缓存