标准答案
- Cache-Control 的 max-age 定义新鲜期,public 允许共享缓存,private 限制为浏览器私有缓存,no-store 要求不保存敏感响应。
- ETag 表示资源版本,客户端使用 If-None-Match 验证;Last-Modified 和 If-Modified-Since 提供时间粒度较粗的替代或补充。
- ETag 与 Last-Modified 主要减少未变化内容的响应体传输,而 Cache-Control 决定是否需要发起验证请求,两者应按资源更新频率配合。
- 用户个人资料、账户余额、订单、权限结果、带 Authorization 的敏感响应和一次性下载链接不能随意被 CDN 或共享代理公开缓存。
- 缓存键还应考虑 Vary、语言、压缩、设备和认证维度,避免一个用户或一种表示被错误复用给另一个请求。
题目解析
缓存错误通常表现为偶发的数据串用户、旧权限或更新不生效,比完全不缓存更难排查。设计时要先区分公共内容和个体化内容。
Last-Modified 可能在秒级精度内遗漏连续更新,ETag 也需要保证同一表示稳定且不同表示能正确变化。
代码示例
公开、可验证的资源可以同时给出新鲜期和版本标识,让缓存命中后再按需验证。
Text
Cache-Control: public, max-age=300
ETag: "article-42-v7"
Vary: Accept-Encoding
If-None-Match: "article-42-v7"
HTTP/1.1 304 Not Modified常见误区
- 把所有 GET 接口都设置为 public 长缓存。
- 只设置 ETag,却没有考虑 Cache-Control 和缓存键。
- 以为带 Authorization 的响应一定不会被任何中间缓存处理。