浏览器缓存与协商缓存

1. 强缓存(Strong Cache)

定义

强缓存是指在缓存的资源有效期内,浏览器会直接使用缓存中的数据,而不会发起网络请求。也就是说,浏览器会直接从本地缓存读取资源,不会与服务器进行任何交互。

如何控制强缓存

强缓存的实现依赖于 HTTP 头部的 Cache-ControlExpires

  • Cache-Control: 控制缓存的策略,主要用于现代浏览器,提供更细粒度的控制。
  • Expires: 指定资源的过期时间。这个头部是 HTTP/1.0 中引入的,过期时间以 GMT 格式表示。

主要指令

  1. Cache-Control: max-age=
    • 该指令表示缓存资源的有效期,单位为秒。
    • 示例:Cache-Control: max-age=3600 表示资源在 3600 秒内有效,即 1 小时内浏览器不会请求服务器。
  2. Expires:
    • 表示资源的过期时间,单位为日期。
    • 示例:Expires: Wed, 21 Oct 2023 07:28:00 GMT 表示缓存资源有效期直到 2023 年 10 月 21 日 07:28:00 GMT。
    • Expires 头是基于客户端的时间,若浏览器的本地时间不准确可能会导致缓存的意外失效。

强缓存工作流程

  • 当浏览器请求资源时,会首先检查缓存中是否存在符合 Cache-ControlExpires 的缓存。
  • 如果缓存有效,浏览器会直接使用缓存,而不会向服务器发起请求。

例子

http 复制代码
Cache-Control: max-age=86400

表示该资源在 86400 秒(即 1 天)内有效,过期后需要重新请求。

2. 协商缓存(Conditional Cache)

定义

协商缓存是指浏览器向服务器发送请求时,即使缓存中有资源,仍然会附带一些条件,询问服务器该资源是否更新。如果服务器认为缓存有效,则返回 304 Not Modified 状态码,不需要重新发送资源。如果缓存过期或有更新,服务器会返回新的资源。

如何控制协商缓存

协商缓存的实现依赖于 Last-ModifiedIf-Modified-Since ,以及 ETagIf-None-Match

  1. Last-ModifiedIf-Modified-Since
    • Last-Modified: 服务器返回资源最后一次修改的时间。
    • If-Modified-Since: 浏览器在请求时携带的请求头,告诉服务器资源上次修改的时间,服务器会检查该时间与当前时间是否一致。
    • 如果自上次修改后没有变化,服务器返回 304 Not Modified,客户端继续使用缓存。
  2. ETagIf-None-Match
    • ETag: 是服务器返回的资源唯一标识符(一般为哈希值),可以判断资源是否变化。
    • If-None-Match : 浏览器发送请求时附带的头,携带当前缓存的 ETag 值,服务器根据该值判断资源是否变化。
    • 如果资源未变更,服务器返回 304 Not Modified,否则返回最新资源。

其实 Etag 和 Last-Modified 一样的,只不过 Etag 是服务端对资源按照一定方式(比如 contenthash)计算出来的唯一标识,就像人类指纹一样,传给客户端之后,客户端再传过来时候,服务端会将其与现在的资源计算出来的唯一标识做比较,一致则返回 304,不一致就返回 200 和新的资源及新的 Etag。

两者比较:

  • 优先使用 Etag。
  • Last-Modified 只能精确到秒级。
  • 如果资源被重复生成,而内容不变,则 Etag 更精确。

协商缓存工作流程

  • 浏览器首先检查是否有缓存,如果有缓存,浏览器会发送请求并携带 If-Modified-SinceIf-None-Match 请求头。
  • 服务器根据这些信息判断资源是否更新,如果未更新,则返回 304 Not Modified,并让浏览器继续使用本地缓存。
  • 如果资源已更新,则返回最新的资源。

例子

  1. 服务器返回资源时:

    http 复制代码
    Last-Modified: Mon, 18 Jan 2023 10:00:00 GMT
  2. 浏览器发起请求时:

    http 复制代码
    If-Modified-Since: Mon, 18 Jan 2023 10:00:00 GMT
  3. 如果资源未修改,服务器返回:

    http 复制代码
    HTTP/1.1 304 Not Modified

3. 强缓存与协商缓存的关系

  • 强缓存 :在缓存有效期内,浏览器不会与服务器交互,直接从缓存读取数据。主要依赖 Cache-ControlExpires 头部。
  • 协商缓存 :即使有缓存,浏览器也会向服务器发送请求,询问缓存是否有效,服务器根据条件判断是否更新缓存。主要依赖 Last-ModifiedETag 以及 If-Modified-SinceIf-None-Match

4. 强缓存和协商缓存的区别

  • 强缓存:直接使用本地缓存,不会向服务器发送请求,速度最快。
  • 协商缓存:浏览器会向服务器询问缓存是否有效,只有在资源变化时才会从服务器获取新的资源。

5. 总结

  • 强缓存 是由浏览器通过 HTTP 头部中的 Cache-ControlExpires 控制的,当缓存有效时,浏览器直接从缓存读取。
  • 协商缓存 依赖于 Last-ModifiedETag,它通过向服务器发送条件请求,确保缓存资源是否更新。优先使用 Etag
  • 强缓存协商缓存 组合使用,可以有效提高性能并减少不必要的网络请求。

三种刷新操作对 http 缓存的影响:

  • 正常操作:地址栏输入 url,跳转链接,前进后退等。强制缓存有效 ,协商缓存有效
  • 手动刷新:f5,点击刷新按钮,右键菜单刷新。强制缓存失效 ,协商缓存有效
  • 强制刷新:ctrl + f5,shift+command+r。强制缓存失效 ,协商缓存失效
相关推荐
旧味清欢|6 分钟前
关注分离(Separation of Concerns)在前端开发中的实践演进:从 XMLHttpRequest 到 Fetch API
javascript·http·es6
热爱编程的小曾23 分钟前
sqli-labs靶场 less 8
前端·数据库·less
gongzemin35 分钟前
React 和 Vue3 在事件传递的区别
前端·vue.js·react.js
Apifox1 小时前
如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
前端·后端·ci/cd
-代号95271 小时前
【JavaScript】十四、轮播图
javascript·css·css3
树上有只程序猿1 小时前
后端思维之高并发处理方案
前端
庸俗今天不摸鱼2 小时前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
QTX187302 小时前
JavaScript 中的原型链与继承
开发语言·javascript·原型模式
黄毛火烧雪下2 小时前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox2 小时前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员