真实面经题目 · 原创解析
浏览器强缓存和协商缓存分别依赖哪些 HTTP 头?
浏览器强缓存主要依赖响应头 Cache-Control 和 Expires,协商缓存主要依赖 ETag/If-None-Match 与 Last-Modified/If-Modified-Since。Cache-Control 的优先级通常高于 Expires,ETag 的优先级通常高于 Last-Modified。
真实面经题目 · 原创解析
浏览器强缓存主要依赖响应头 Cache-Control 和 Expires,协商缓存主要依赖 ETag/If-None-Match 与 Last-Modified/If-Modified-Since。Cache-Control 的优先级通常高于 Expires,ETag 的优先级通常高于 Last-Modified。
强缓存是浏览器在缓存有效期内直接使用本地副本,不向服务器发送请求。它主要依赖响应头 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 让浏览器每次校验。
强缓存由响应头告诉浏览器资源在多久内可以直接复用。Cache-Control: max-age=秒数 是现代最常用方式,表示从响应时间开始的相对有效期;Expires 是绝对过期时间。两者同时存在时,通常以 Cache-Control 为准,因为它不依赖客户端本地时钟是否准确。
max-age 定义浏览器缓存有效期,s-maxage 常用于共享缓存,public 表示可被共享缓存保存,private 表示只给单个用户缓存,no-store 表示不存储,no-cache 表示可以存但每次使用前必须校验。很多人误以为 no-cache 是不缓存,其实它强调重新验证。
协商缓存需要请求和响应配合。服务端返回 ETag,浏览器下次带 If-None-Match;服务端返回 Last-Modified,浏览器下次带 If-Modified-Since。服务器比较资源标识或修改时间,未变化返回 304,变化则返回新内容和新的缓存头。
ETag 通常是资源版本标识,可以更精确地区分内容是否变化;Last-Modified 是最后修改时间,精度可能只有秒级,也可能受文件时间、部署方式和时钟影响。两者同时存在时,服务端通常优先使用 ETag 对应的 If-None-Match。
带内容 hash 的 JS、CSS、字体和静态媒体可以设置较长 max-age,因为内容变化会生成新 URL。HTML 入口不适合长期强缓存,否则用户可能拿不到最新资源引用,通常使用 no-cache 或较短 max-age,让浏览器通过协商确认入口是否变化。
no-cache 允许缓存保存副本,但每次使用前必须向服务器验证;no-store 要求不存储请求或响应内容。敏感页面更倾向 no-store,普通入口更新控制常用 no-cache。
ETag 可以基于内容 hash、版本号或构建标识生成,能识别秒级内多次变化,也能避免修改时间变化但内容未变的误判。Last-Modified 受时间精度和部署文件时间影响更大。
通常不会。强缓存有效时浏览器直接复用本地副本,不发起网络请求。只有强缓存过期或策略要求重新验证时,才会带条件请求头进入协商缓存流程。
HTML 往往承载最新 JS、CSS 文件引用。如果 HTML 被长期强缓存,即使静态资源文件名已经更新,用户仍可能拿着旧入口,导致页面版本滞后或资源引用错误。