Skip to main content

Cache-Control:no-cache 与 no-store 区别

no-storeno-cache 是 HTTP 缓存头(Cache-Control)中最容易混淆的两个指令。它们的核心区别在于:no-cache 允许缓存,但使用前必须验证;no-store 彻底禁止缓存,连存都不准存。

为了方便记忆,你可以这样理解: no-cache = 有缓存,但不信任,每次都问一下服务器。 no-store = 坚决不存任何副本,用完即焚。

以下是详细对比:

1. 核心机制对比

特性no-cacheno-store
是否允许存储允许。浏览器和代理服务器可以将响应存入硬盘或内存。禁止。不得以任何形式(内存、硬盘)保存响应副本。
使用缓存前必须重新验证。每次使用缓存时,都必须向源服务器发起条件请求(携带 If-Modified-SinceETag)。不涉及验证。因为根本没存,每次都直接请求源服务器获取完整数据。
服务器返回 304 时若服务器返回 304 Not Modified,则可继续使用已存储的旧缓存。永远不会发生 304,因为客户端没有缓存可用,服务器必须返回 200 完整数据。
网络开销每次都有验证请求(请求头小,响应体无或小)。每次都有完整请求(请求头 + 完整的响应体)。

2. 实际浏览器行为差异(关键)

  • no-cache 场景:你访问页面,浏览器发现有缓存,但标了 no-cache。浏览器会连接服务器问一句:“这个资源有没有变?”(发 ETag)。服务器说:“没变”(304),浏览器就直接展示本地缓存,省下了下载图片/JS/CSS 的带宽和时间。
  • no-store 场景:你访问页面,浏览器发现有缓存,但标了 no-store。浏览器直接忽略该缓存(甚至不会写入磁盘),立刻向服务器请求完整的新数据。就算服务器没变,也必须把完整的 HTML/数据重新下载一遍。

3. 涉及敏感信息时的安全语义(RFC 规范)

在 HTTP 规范(RFC 9111)中,no-store 不仅仅是“不缓存”,它还包含隐私安全的考量:

  • 即使请求/响应需要存到非持久性存储(比如浏览器的内存缓存)以便前进/后退时快速展示,理论上也不应该存储(必须尽量清除)。
  • no-cache 没有这个安全约束,它只关乎“新鲜度”,不关乎“保密性”。

4. 常见误用纠正

很多开发者误以为 no-cache 就是“不缓存”,这是绝对错误的。如果你希望页面完全不缓存,每次都拿最新的,正确的写法是 no-store,而不是 no-cache

  • 错误Cache-Control: no-cache (浏览器依然会存,只是每次去问一下,如果服务器宕机或网络差,甚至可能直接报错无法访问,因为验证失败)。
  • 正确Cache-Control: no-store, must-revalidate (用于交易页、支付页、验证码、实时股价)。

5. 最佳实践组合

在实际生产环境中,它们通常配合 must-revalidate 使用:

  • 用于 HTML 页面(动态内容)Cache-Control: no-cache, must-revalidate (每次都检查 HTML 是否有更新)。
  • 用于敏感隐私数据(订单/支付)Cache-Control: no-store, no-cache, must-revalidate (彻底不存,同时保证即使有历史缓存也要验证)。
  • 用于静态资源(带 hash 的 JS/CSS/图片)Cache-Control: public, max-age=31536000, immutable (一年内强缓存,根本不用 no-cache)。