动态接口缓存需区分private(用户专属,如登录态,设Cache-Control: private, max-age=300)与public(通用内容,如商品分类,设Cache-Control: public, s-maxage=600, max-age=120);CDN仅认s-maxage,须显式声明且排除private;敏感操作禁用缓存并主动清理;推荐流等可用stale-while-revalidate提升体验。

动态接口响应的缓存控制,关键在于让浏览器和 CDN 各自按需缓存——浏览器可存用户专属数据,CDN 则只缓通用内容。JavaScript 本身不能设置响应头,但你可以通过后端配置 + 前端配合逻辑,精准区分 private 与 public 场景。
明确区分 private 和 public 的适用边界
private 表示“仅当前用户可用”,比如返回登录态、个人订单列表、未读消息数等含身份标识的数据;public 则适用于所有用户一致的内容,如商品分类、热门标签、活动 banner 等通用接口响应。
• 含 Cookie、Authorization 或用户 ID 参数的请求,响应头应设 Cache-Control: private, max-age=300(浏览器缓 5 分钟,CDN 不存)
• 不依赖用户状态的 GET 接口(如 /api/v1/categories),应设 Cache-Control: public, s-maxage=600, max-age=120(CDN 缓 10 分钟,浏览器缓 2 分钟)
s-maxage 是 CDN 缓存的唯一可靠指令
只写 max-age=300 对 CDN 几乎无效——多数 CDN(Cloudflare、阿里云、Fastly)会直接忽略带 private 的响应,或因策略默认跳过缓存。
• 若你希望 CDN 缓存某类动态接口,必须同时满足两个条件:
✓ 响应头不含 private 或 no-cache
✓ 显式声明 s-maxage,例如 public, s-maxage=1800, max-age=60
• 注意:s-maxage 会覆盖同响应中的 max-age,专供共享缓存使用,浏览器不认它
敏感操作要禁用缓存并主动清理
POST/PUT/DELETE 类请求的响应,默认不应被缓存。即使服务端误加了缓存头,前端也应强制规避:
• 发起请求时加 cache: 'no-store' 选项:
fetch('/api/v1/order', { method: 'POST', cache: 'no-store' })
• 用户登出、修改关键设置后,主动清除 localStorage 中相关缓存键(如 localStorage.removeItem('cache_/api/v1/profile'))
• 避免把 token、临时凭证等敏感字段混在缓存数据中,只缓结构化业务数据
用 stale-while-revalidate 提升体验连贯性
对既需要一定实时性、又不能忍受白屏或加载延迟的接口(如首页推荐流),可叠加该策略:Cache-Control: public, s-maxage=300, max-age=60, stale-while-revalidate=300
意思是:CDN 缓 5 分钟,浏览器只信 1 分钟;过期后 5 分钟内仍可秒出旧数据,同时后台静默拉新。这样既防抖动,又保新鲜。实际效果是用户几乎感知不到“刷新等待”。


















