前提:此篇文章涉及Cache-Control,Expires,Etag,Last-Modified详细解释,以及缓存策略实例。
总结:http协议通过Expires(http1.0)和Cache-Control(http1.1)来设置缓存,又通过Last-Modified/If-Modified-since和Etag/If-None-Match来验证缓存的状态(是否失效)
1.先来详细说说Cache-Control
| Cache-Control | |
|---|---|
| max-age | 资源可强缓存的时间(相对) |
| no-cache | 不用强缓存,使用协商缓存,例如:每次打开index.html时,浏览器都会发出请求,询问资源是否修改,修改则返回新的响应体,无修改则只返回响应头,响应体是空的 |
| no-store | 不能进行缓存,每次访问该资源,都要发请求,而服务器直接返回响应体,因为没有缓存 |
| private | 单个用户缓存可以保存,而共享缓存(如CDN)不能缓存 |
| public | 全部都可以缓存 |
1.1 Cache-Control和Expires区别
- Expires(http1.0),Cache-Control(http1.1),Expires已经过时,目前是为了兼容。
- Expires是具体的时间,没有Cache-Control好控制。例:如果客户端时间和浏览器时间相差太大,Expires将变得没有意义。
2.Last-Modified和Etag如何工作
2.1 Last-Modified
graph TD
浏览器发送请求 --> 服务器返回响应体和头包括LastModified
服务器返回响应体和头包括LastModified--> 资源缓存超过时间
资源缓存超过时间 --> 浏览器携带If-Modified-Since发送请求
浏览器携带If-Modified-Since发送请求 -->浏览器判断自己的Last-Modified和浏览器携带的If-Modified-Since并做出选择
2.2 Etag
Etag作用原理与Last-Modified类似,不过Etag代表的是当前资源的版本号
2.3 Last-Modified和Etag区别
- Last-Modified精确度低于Etag.前者(Last-Modified)精确度在秒,如果在1s内多次修改文件,前者并不能体现文件已经被修改。如果是负载均衡的服务器,各个服务器生成的Last-Modified也会不一样。
- Last-Modified的性能高于Etag.前者只需要记录一个时间(最小精度为秒),而后者需要通过算法来计算一个hash值。
- 服务器优先考虑Etag
3.缓存策略
- max-age
- max-age+Etag
- max-age+Last-Modified
详细描述,下面的第二个链接可以找到
4.缓存的位置
4.1 from memory cache
1.不用访问服务器,资源存放在内存中
2.关闭网页后,该资源被删除
3.一般来说,js文件存放在该位置
4.2 from disk cache
1.不用访问服务器,资源存放在硬盘中
2.关闭网页后,该资源不会被删除
3.访问速度很慢
4.3 三级缓存原理
- 先访问内存
- 内存查不到,再访问硬盘
- 硬盘查不到,再发送网络请求,请响应体存在内存和硬盘
重要参考资料(站在巨人肩膀上的我)
浏览器缓存的起点
Expires、Cache-Control、Last-Modified和Etag总结
Chrome浏览器: memory cache vs dist cache