决策链:浏览器请求资源前先查强缓存,Cache-Control: max-age=31536000 未过期就直接用本地副本(状态显示 from disk/memory cache,请求根本不发出);过期或缺失才走协商缓存——带上 If-None-Match(对应 ETag)或 If-Modified-Since(对应 Last-Modified)问服务器,资源没变返回 304 用本地副本,变了返回 200 带新内容。协商缓存省流量不省请求数,强缓存两个都省。
优先级细节:Cache-Control 压过 Expires(后者是绝对时间,客户端时钟不准就失效);ETag 压过 Last-Modified(后者精度只到秒,一秒内多次修改识别不了,且某些生成型内容修改时间一直在变内容却没变)。no-cache 不是不缓存,是每次都协商;no-store 才是彻底不缓存。
前端发版标准策略:HTML 文件 Cache-Control: no-cache(每次协商,保证入口新鲜),JS/CSS/图片带内容 hash 文件名(app.3f8a2c.js)配 max-age=31536000, immutable 永久强缓存——内容一变 hash 就变,URL 变了自然拉新的,旧文件缓存自然废弃。发版后用户看不到新页面的事故,十有八九是 HTML 被强缓存了(nginx 对 html 误配了长 max-age,或者 CDN 缓存了 HTML),检查顺序:先看 HTML 响应头,再查 CDN 缓存规则。