标准答案

  1. Cache-Control 的 max-age 定义新鲜期,public 允许共享缓存,private 限制为浏览器私有缓存,no-store 要求不保存敏感响应。
  2. ETag 表示资源版本,客户端使用 If-None-Match 验证;Last-Modified 和 If-Modified-Since 提供时间粒度较粗的替代或补充。
  3. ETag 与 Last-Modified 主要减少未变化内容的响应体传输,而 Cache-Control 决定是否需要发起验证请求,两者应按资源更新频率配合。
  4. 用户个人资料、账户余额、订单、权限结果、带 Authorization 的敏感响应和一次性下载链接不能随意被 CDN 或共享代理公开缓存。
  5. 缓存键还应考虑 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 的响应一定不会被任何中间缓存处理。

作者信息