浏览器缓存与协商缓存

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 分钟前
JavaScript面向对象
开发语言·javascript·ecmascript
檀越剑指大厂9 分钟前
【Python系列】异步 Web 服务器
服务器·前端·python
我是Superman丶11 分钟前
【前端】js vue 屏蔽BackSpace键删除键导致页面后退的方法
开发语言·前端·javascript
Hello Dam12 分钟前
基于 Spring Boot 实现图片的服务器本地存储及前端回显
服务器·前端·spring boot
LightOfNight13 分钟前
Redis设计与实现第14章 -- 服务器 总结(命令执行器 serverCron函数 初始化)
服务器·数据库·redis·分布式·后端·缓存·中间件
小仓桑14 分钟前
利用 Vue 组合式 API 与 requestAnimationFrame 优化大量元素渲染
前端·javascript·vue.js
Hacker_xingchen14 分钟前
Web 学习笔记 - 网络安全
前端·笔记·学习
天海奈奈15 分钟前
前端应用界面的展示与优化(记录)
前端
多多*36 分钟前
后端并发编程操作简述 Java高并发程序设计 六类并发容器 七种线程池 四种阻塞队列
java·开发语言·前端·数据结构·算法·状态模式
ᥬ 小月亮38 分钟前
Layui表格的分页下拉框新增“全部”选项
android·javascript·layui