cache-control: public 的核心作用是允许所有中间代理(如 cdn、isp 缓存)缓存并共享响应,但需配合 max-age、s-maxage 等指令才生效,且不可用于含用户个性化数据的接口。

Cache-Control: public 的核心作用是明确告诉所有中间代理(如 CDN、公司网关、ISP 缓存服务器等):该响应可以被缓存,并且可以被多个用户共享。它本身不开启缓存,而是“解除限制”——允许原本因敏感性(如含 Cookie 或认证头)而被默认禁止缓存的响应,进入多级代理缓存链。
必须配合其他缓存指令才真正生效
仅写 Cache-Control: public 是不够的。中间代理通常还要求明确的缓存时长或验证机制,否则可能忽略缓存。常见有效组合:
-
Cache-Control: public, max-age=3600—— 允许各级代理缓存 1 小时,同一资源可服务多个用户 -
Cache-Control: public, s-maxage=7200—— 专为共享缓存(如 CDN)设置 2 小时,不影响客户端 private 缓存逻辑 -
Cache-Control: public, immutable—— 告诉代理“此资源永不变更”,适合带哈希指纹的静态资源(如main.a1b2c3.js)
注意响应头与请求上下文的匹配性
即使设置了 public,若响应中包含以下内容,部分代理仍会拒绝缓存:
- Set-Cookie 头(除非你明确配置代理支持带 Cookie 的 public 缓存,如某些 CDN 的 “cache key ignore cookie” 功能)
- Vary 头值过于宽泛(例如
Vary: User-Agent会让缓存碎片化;建议只用Vary: Accept-Encoding或Vary: Origin) - 状态码非缓存友好型(如 200、203、206、300、301、410 可缓存;而 401、403、500 默认不缓存,即使加 public 也常被忽略)
验证是否真正被中间代理缓存
不能只看浏览器 DevTools 的 “from disk cache”。需确认链路中真实代理行为:
- 查看响应头中的
X-Cache(Cloudflare)、X-Cache-Hits(AWS CloudFront)、X-Served-By(Fastly)等 CDN 特有字段 - 用
curl -I多次请求,观察Age头是否递增(表示代理命中并更新了 Age) - 在不同网络环境(如手机 4G、家庭宽带、公司内网)重复请求,比对响应时间与
via头中代理节点是否一致
慎用于含用户个性化内容的接口
public 意味着“任何用户都可拿到同一份缓存副本”。若接口返回数据依赖登录态(如 /api/user/profile),即使加了 public,也会导致 A 用户看到 B 用户的数据。此时应:
- 改用
private(仅浏览器可缓存) - 剥离个性化部分,用前端 JS 动态拼接(如缓存公共模板 + 单独请求用户信息)
- 使用
stale-while-revalidate配合 ETag 实现安全兜底











