Cache-Control 在管什么
Cache-Control 用一组逗号分隔的指令告诉缓存「这份响应能不能存、能存多久、过期以后怎么办」,请求侧和响应侧都可以用。它是 HTTP 缓存行为的总开关:max-age 决定新鲜期长度,no-store 直接禁止落盘,private 与 public 决定 CDN 这类共享缓存能不能复用,must-revalidate 用来约束过期后的行为。浏览器与 CDN 对同一条指令的落实程度并不完全一致,设计时要按最保守的一侧来定。
响应侧指令速查
| 指令 | 作用 | 常见用法 |
|---|---|---|
| max-age=N | 新鲜期 N 秒,期内直接用本地副本 | 静态资源按内容哈希配长有效期 |
| s-maxage=N | 共享缓存专用新鲜期,覆盖 max-age | CDN 与浏览器分离控制 |
| no-cache | 可以存储,但每次使用前必须再验证 | 需要强一致但想省带宽的接口 |
| no-store | 完全不存储,不写磁盘也不写内存 | 含敏感信息的响应 |
| private | 只允许浏览器缓存,共享缓存禁止 | 带用户身份的页面 |
| must-revalidate | 过期后禁止使用陈旧副本,必须回源验证 | 金额与库存这类敏感数据 |
| immutable | 新鲜期内绝不发起再验证 | 带哈希名的静态文件 |
| stale-while-revalidate=N | 过期后 N 秒内先用旧副本并后台刷新 | 可用性优先的列表页 |
| stale-if-error=N | 回源出错时 N 秒内可用旧副本兜底 | 降低源站抖动对用户的影响 |
| no-transform | 禁止中间代理改写内容 | 不希望被压缩或转码的响应 |
组合示例与逐行含义
组合示例与逐行含义
Cache-Control: public, max-age=60, stale-while-revalidate=300, stale-if-error=86400
# public 允许 CDN 等共享缓存保存
# max-age=60 六十秒内直接用本地副本,不回源
# stale-while-revalidate=300 过期后五分钟内先返回旧内容,同时后台刷新
# stale-if-error=86400 回源失败时一天内用旧副本兜底,保住可用性请求侧写法
| 指令 | 请求侧含义 | 典型场景 |
|---|---|---|
| max-age=N | 我接受的副本年龄上限,超过就回源 | 避免拿到太旧的数据 |
| no-cache | 要求回源重新验证后再给我 | 手动刷新、强一致读取 |
| no-store | 连缓存都不要用 | 隐私模式与敏感操作 |
| only-if-cached | 只接受缓存命中,否则回 504 | 离线浏览、弱网容错 |
| max-stale=N | 愿意接受过期不超过 N 秒的副本 | 离线可用优先的场景 |
stale-while-revalidate 与 stale-if-error 对可用性提升明显,主流 CDN 都支持;但一致性要求高的接口不要配,用户可能反复看到过期数据。
no-cache 与 no-store 常被写反:no-cache 允许存储、只要求先验证,no-store 才是不留任何副本。要处理敏感数据时写错成 no-cache,内容仍会落到磁盘。