浏览器缓存机制
现代浏览器里,我们打开一个网页,都会发起 http 请求,浏览器请求下载完资源后,会对数据进行缓存,以保证更快的响应速度。浏览器存放缓存有以下几个地方:
Service Worker
一个独立线程,可以用做离线缓存Memory Cache
内存缓存Disk Cache
磁盘缓存Push Cache
推送缓存,与 HTTP2 有关
缓存分类
分为 强缓存
和 协商缓存
强缓存
有两个属性: Expires
和 Cache-Control
。前者是 http1.0 的产物,表示资源的过期时间;后者是 http1.1 新增的更全的属性控制,优先级 Cache-Control > Expires。
Cache-Control 有如下属性:
- max-age: 缓存会在多少秒后过期
- s-maxage: 与 max-age 的区别在于,它只适用于公共缓存服务器
- public: 表示该资源可以被任意节点缓存(客户端,代理服务器等等)
- private: 表示该资源不会被代理服务器缓存
- no-cache: 客户端可以缓存资源,但每次使用前,必须向服务器确认其有效性
- no-store: 顾名思义,不进行缓存
协商缓存
相关属性: Last-Modified
和 ETag
。
Last-Modified 表示文件的最后修改时间,每次请求时,把它的值作为 If-Modified-Since 发送给服务器,服务器会验证在该时间后资源是否有更新,有就返回新的资源并更新 Last-Modified;没有就返回 304。
ETag 类似文件指纹,每次请求会将 ETag 作为 If-None-Match 发送给服务器,服务器就会验证这个资源对应的 ETag 是否有变动,有就返回新资源;没有就返回 304。
由于 Last-Modified 受限于本地时间,即修改本地时间后可能会影响到缓存的有效性;而 ETag 是对文件内容生成哈希值,就像指纹一一样有唯一标识,因此服务器会优先使用 ETag ,然后才是 Last-Modified 。
启发式缓存
如果请求头啥都没设置怎么办?浏览器默认会采用一种启发式缓存的算法。具体就是用响应头的 Date 减去 Last-Modified 值的 10% 作为缓存时间。
缓存过程
- 初次发起请求,服务器响应 200 状态码,下载拿到资源后,对 response 进行缓存;
- 当再次加载该资源时,浏览器优先判断强缓存,比较当前时间与上次返回 200 的时间差,是否超过了 cache-control 设置的 max-age。如果没有超过,命中强缓存就不用去发请求了,直接读取缓存结果返回;如果超过了,那就发起请求,这时请求头中会带上 If-None-Match 和 If-Modifed-Since 的标识
- 服务器收到了浏览器请求后,开始协商缓存。
3.1 优先根据 Etag 的值判断文件资源是否被修改,如果没有,则命中协商缓存,返回 304;如果被修改了,那就生成新的 Etag 值,然后返回新的资源文件,状态码是 200
3.2 如果没有 Etag,那就看 If-Modifed-Since ,跟资源文件的最后修改时间做比对,如果相同,命中协商缓存返回 304;否则更新 last-modifed 并返回新的资源文件,状态码是 200
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论