真实面经题目 · 原创解析

浏览器强缓存和协商缓存分别依赖哪些 HTTP 头?

浏览器强缓存主要依赖响应头 Cache-Control 和 Expires,协商缓存主要依赖 ETag/If-None-Match 与 Last-Modified/If-Modified-Since。Cache-Control 的优先级通常高于 Expires,ETag 的优先级通常高于 Last-Modified。

出现于:字节跳动 · 前端

60 秒回答模板

强缓存是浏览器在缓存有效期内直接使用本地副本,不向服务器发送请求。它主要依赖响应头 Cache-Control 和 Expires:Cache-Control 可以设置 max-age、s-maxage、public、private、no-store、no-cache、must-revalidate 等指令;Expires 是一个绝对过期时间,受客户端时间影响,优先级通常低于 Cache-Control。协商缓存是在缓存过期或要求校验时,浏览器向服务器发起条件请求。它依赖两组头:ETag 和 If-None-Match,Last-Modified 和 If-Modified-Since。服务端判断资源未变化返回 304,浏览器继续使用本地缓存;如果资源变化则返回 200 和新内容。实践中静态资源常用长 Cache-Control 配合内容 hash,HTML 入口常用 no-cache 让浏览器每次校验。

考点 强缓存头
难度 真实面经高频题
回答目标 讲清机制、边界和追问

深入解析

01

强缓存的核心头

强缓存由响应头告诉浏览器资源在多久内可以直接复用。Cache-Control: max-age=秒数 是现代最常用方式,表示从响应时间开始的相对有效期;Expires 是绝对过期时间。两者同时存在时,通常以 Cache-Control 为准,因为它不依赖客户端本地时钟是否准确。

02

Cache-Control 常见指令

max-age 定义浏览器缓存有效期,s-maxage 常用于共享缓存,public 表示可被共享缓存保存,private 表示只给单个用户缓存,no-store 表示不存储,no-cache 表示可以存但每次使用前必须校验。很多人误以为 no-cache 是不缓存,其实它强调重新验证。

03

协商缓存的两组头

协商缓存需要请求和响应配合。服务端返回 ETag,浏览器下次带 If-None-Match;服务端返回 Last-Modified,浏览器下次带 If-Modified-Since。服务器比较资源标识或修改时间,未变化返回 304,变化则返回新内容和新的缓存头。

04

ETag 与 Last-Modified

ETag 通常是资源版本标识,可以更精确地区分内容是否变化;Last-Modified 是最后修改时间,精度可能只有秒级,也可能受文件时间、部署方式和时钟影响。两者同时存在时,服务端通常优先使用 ETag 对应的 If-None-Match。

05

资源类型决定策略

带内容 hash 的 JS、CSS、字体和静态媒体可以设置较长 max-age,因为内容变化会生成新 URL。HTML 入口不适合长期强缓存,否则用户可能拿不到最新资源引用,通常使用 no-cache 或较短 max-age,让浏览器通过协商确认入口是否变化。

易错点

  • 把 no-cache 理解成完全不缓存,混淆 no-cache 和 no-store。
  • 只记 Expires,忽略 Cache-Control 的现代优先级和更多指令。
  • 把 ETag 写成请求头,忽略响应头 ETag 和请求头 If-None-Match 的配对关系。
  • 给 HTML 和带 hash 的静态资源使用同一套长期缓存策略。

面试官追问

Cache-Control: no-cache 和 no-store 有什么区别?

no-cache 允许缓存保存副本,但每次使用前必须向服务器验证;no-store 要求不存储请求或响应内容。敏感页面更倾向 no-store,普通入口更新控制常用 no-cache。

为什么 ETag 通常比 Last-Modified 更可靠?

ETag 可以基于内容 hash、版本号或构建标识生成,能识别秒级内多次变化,也能避免修改时间变化但内容未变的误判。Last-Modified 受时间精度和部署文件时间影响更大。

强缓存命中时请求头里会带 If-None-Match 吗?

通常不会。强缓存有效时浏览器直接复用本地副本,不发起网络请求。只有强缓存过期或策略要求重新验证时,才会带条件请求头进入协商缓存流程。

为什么 HTML 不建议设置一年强缓存?

HTML 往往承载最新 JS、CSS 文件引用。如果 HTML 被长期强缓存,即使静态资源文件名已经更新,用户仍可能拿着旧入口,导致页面版本滞后或资源引用错误。