HTTP 缓存让浏览器或中间缓存复用响应,减少网络传输和源站负载。缓存是否可用取决于请求方法、响应指令、状态、共享/私有缓存身份和验证器等,不是“GET 一定缓存”。
强缓存主要由 Cache-Control: max-age=... 等新鲜度指令决定。响应仍新鲜时,缓存可以直接使用,不必向服务器验证。no-cache 的含义是使用前需要验证,并非禁止存储;no-store 才要求不存储。private 限制共享缓存保存,public 可允许共享缓存保存,但仍要满足其他规则。
响应可带 ETag 或 Last-Modified 作为验证器。缓存过期后发 If-None-Match 或 If-Modified-Since 条件请求;资源未变化时服务器返回 304 Not Modified,浏览器复用本地响应主体并更新元数据;变化时返回新表示。通常 ETag 优先用于验证。Vary 会使缓存按指定请求头区分变体,例如压缩编码。
缓存能否安全使用取决于内容是否个性化以及正确配置。共享代理缓存错误保存带用户信息的响应可能造成数据泄露;部署静态资源常用内容哈希文件名配长缓存,而 HTML 入口使用较短缓存以便更新。
缓存键通常包含请求方法、目标 URI 以及 Vary 声明的请求头;Cookie、Authorization 等凭证也会影响共享缓存是否可复用。排查“改了文件但用户仍看到旧内容”时,检查浏览器缓存、Service Worker、CDN 缓存键和源站响应头,并通过版本化资源名降低缓存失效依赖。清 CDN 缓存只能解决某一层,其他缓存仍可能保留旧响应。
常见追问
no-cache 和 no-store 有什么区别?
no-cache 允许存储,但复用前必须向源站验证;no-store 要求缓存不要存储该响应。实际还需结合请求/响应方向和缓存类型理解。
304 响应有没有响应体?
304 用于条件请求确认缓存表示仍可用,客户端复用已有主体;它不重新传输完整表示内容。
ETag 和 Last-Modified 如何选择?
ETag 是实体标签,适合按表示标识验证;Last-Modified 按时间验证,精度及源站时钟等因素可能限制判断。服务器可同时提供,客户端/缓存按协议规则使用。
用户登录后的页面能被 CDN 缓存吗?
需要谨慎。必须按共享缓存规则与响应指令判断;包含用户私有数据的响应通常应限制为私有或禁止存储,避免不同用户间复用。