基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

HTTP 响应头中的 Cache-Control、Expires、Last-Modified、Etag 分别起什么作用?

知识点图片

这四个 HTTP 响应头主要用于控制浏览器的缓存机制。为了更好地理解它们,我们需要将它们分为两类:

  1. 强缓存(Freshness / Expiration): 决定浏览器是否不需要向服务器发送请求,直接从本地缓存读取。
    • 涉及字段:ExpiresCache-Control
  2. 协商缓存(Validation): 当强缓存失效后,浏览器向服务器发送请求,询问缓存是否仍然有效(即文件是否修改过)。
    • 涉及字段:Last-ModifiedEtag

以下是详细的解释和对比:


一、 强缓存阶段 (决定是否发起请求)

如果强缓存生效,浏览器状态码通常显示为 200 (from memory cache)200 (from disk cache)不会向服务器发送网络请求

1. Expires (HTTP/1.0)

  • 作用: 指定资源过期的绝对时间(服务器端的时间点)。
  • 格式: GMT 格式的时间字符串,例如:Expires: Wed, 21 Oct 2023 07:28:00 GMT
  • 原理: 浏览器拿本地系统时间与这个时间对比。如果本地时间小于 Expires,则直接使用缓存。
  • 缺点:
    • 它依赖于客户端的本地时间。如果用户修改了电脑时间,或者客户端与服务器时间不一致,会导致缓存判断错误。
    • 这是 HTTP/1.0 的产物,现在主要用于向后兼容。

2. Cache-Control (HTTP/1.1)

  • 作用: 用于控制缓存行为的通用首部,功能比 Expires 强大且优先级更高。
  • 常见指令:
    • max-age=3600:表示资源在 3600 秒(1小时)后过期。这是相对时间,解决了 Expires 的时间同步问题。
    • no-cache不要被名字误导。它表示使用缓存前必须向服务器确认(即跳过强缓存,直接进入协商缓存阶段)。
    • no-store:禁止任何缓存,每次都必须从服务器下载完整的最新资源。
    • public / private:决定资源是否可以被中间代理服务器(CDN)缓存。
  • 优先级:Cache-Control: max-ageExpires 同时存在时,Cache-Control 优先级更高

二、 协商缓存阶段 (决定是否使用旧资源)

当强缓存失效(例如 max-age 到期了),浏览器会向服务器发起请求。服务器会根据以下字段判断文件是否真的修改了。如果未修改,返回 304 Not Modified(告诉浏览器继续用旧的);如果修改了,返回 200 OK 和新文件。

3. Last-Modified (基于时间)

  • 作用: 服务器告诉浏览器该资源的最后修改时间
  • 配合请求头: If-Modified-Since
  • 工作流程:
    1. 服务器响应头带上 Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
    2. 缓存过期后,浏览器再次请求该资源时,请求头会带上 If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
    3. 服务器检查:如果文件最后修改时间等于该时间,返回 304;如果文件更新了,返回 200 和新内容。
  • 缺点:
    • 精度问题: 只能精确到。如果在 1 秒内文件被修改了多次,它无法感知。
    • 内容未变时间变: 如果只是打开文件保存了一下(修改时间变了),但内容没变,服务器也会误判为文件更新了,导致重新传输。

4. Etag (基于内容/指纹)

  • 作用: 服务器根据文件内容生成的唯一标识符(哈希值或指纹),例如 Etag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  • 配合请求头: If-None-Match
  • 工作流程:
    1. 服务器响应头带上 Etag
    2. 缓存过期后,浏览器再次请求,请求头带上 If-None-Match: "33a64df5..."
    3. 服务器重新计算当前文件的 Hash 值进行对比:如果一致,返回 304;如果不一致,返回 200 和新内容。
  • 优点: 精度最高,只要内容变了 Etag 就会变。
  • 缺点: 服务器计算 Etag 需要消耗 CPU 资源(尤其是大文件)。
  • 优先级:EtagLast-Modified 同时存在时,服务器优先校验 Etag

三、 总结与优先级流程

优先级对比

  1. 强缓存: Cache-Control > Expires
  2. 协商缓存: Etag > Last-Modified

浏览器请求资源的完整流程

  1. 浏览器发起请求
  2. 检查强缓存:
    • 检查 Cache-Control (max-age) 或 Expires
    • 如果未过期 -> 直接使用缓存 (200 OK, from cache)
    • 如果已过期 -> 进入下一步
  3. 发起网络请求(协商缓存):
    • 请求头携带 If-None-Match (对应之前的 Etag) 和 If-Modified-Since (对应之前的 Last-Modified)。
  4. 服务器处理:
    • 先检查 Etag: 如果不匹配 -> 返回 200 OK + 新资源 + 新 Etag。
    • 如果 Etag 匹配 -> 再检查 Last-Modified
    • 如果 Last-Modified 也不匹配 (极少见情况) -> 返回 200 OK
    • 如果都匹配 -> 返回 304 Not Modified (浏览器收到 304 后,从本地缓存读取数据渲染)。

一张表概括

字段 类别 依赖依据 优先级 优点 缺点
Expires 强缓存 绝对时间 兼容性好 受客户端时间影响
Cache-Control 强缓存 相对时间/指令 精准、功能多 HTTP/1.1 支持
Last-Modified 协商缓存 修改时间戳 计算快 精度仅为秒,可能内容没变时间变
Etag 协商缓存 内容哈希/指纹 精度高,内容变才变 计算消耗服务器性能
00:00
00:00