← 返回题目列表

HTTP 的 Vary 响应头有什么用?它和缓存命中有什么关系?

中等 第 22 / 32 题 更新于 2026/08/02
HTTP缓存响应头

简化版

Vary 用来告诉缓存系统:同一个 URL 的响应不仅取决于 URL,还取决于某些请求头。

例如 Vary: Accept-Encoding 表示缓存要按客户端支持的压缩算法区分副本;Vary: Accept-Language 表示要按语言区分副本。

它能保证缓存正确性,但如果维度过多,会降低缓存命中率。

详细版

典型响应:

HTTP/1.1 200 OK
Content-Encoding: br
Vary: Accept-Encoding

这表示对于同一个 URL,支持 br 的客户端和只支持 gzip 的客户端可能拿到不同响应。

缓存代理不能只用 URL 做 key,还要把请求里的 Accept-Encoding 纳入缓存 key。

另一个例子:

Vary: Accept-Language

表示中文用户和英文用户可能拿到不同页面。

Vary 设置不当会出问题:漏设置可能把错误版本发给用户;设置过多可能导致缓存碎片化。

完整版教学

1. 先理解缓存为什么需要 Vary

HTTP 缓存默认很容易让人误解为“URL 相同,响应就相同”。

但真实服务里,同一个 URL 可能根据请求头返回不同内容。

例如:

  • 根据 Accept-Encoding 返回 gzip 或 br。
  • 根据 Accept-Language 返回中文或英文。
  • 根据 User-Agent 返回移动端或桌面端内容。

Vary 就是服务端告诉缓存:这个响应会受到哪些请求头影响。

Vary 的本质是扩展缓存 key,避免不同请求变体互相污染。

2. Vary: Accept-Encoding 最常见

压缩响应经常带:

Vary: Accept-Encoding
Content-Encoding: gzip

因为不同客户端支持的压缩算法不同。

如果 CDN 只按 URL 缓存,可能把 Brotli 响应发给不支持 Brotli 的客户端。

加入 Vary: Accept-Encoding 后,缓存会把不同 Accept-Encoding 的请求分成不同副本。

这能保证内容可正确解码。

3. Vary 会影响缓存命中率

Vary 增加了缓存 key 的维度。

维度越多,缓存越细,命中率可能越低。

Vary 设置缓存副本数量正确性命中率影响
无 Vary可能错误高但危险
Accept-Encoding适中通常必要可接受
Accept-Language较多多语言必要有下降
User-Agent很多易碎片化明显下降
*不可复用最保守基本无法共享

所以 Vary 不是越多越好。

它要精确表达影响响应内容的请求头。

4. 多语言和内容协商场景

假设同一个路径 /docs 对不同语言返回不同内容。

服务端可能响应:

Content-Language: zh-CN
Vary: Accept-Language

这样缓存知道中文请求和英文请求不能共用同一份响应。

如果不加 Vary,英文用户可能看到中文页面。

如果语言维度过细,例如把每种复杂语言优先级组合都作为 key,缓存命中率会很差。

工程上常会把语言归一化成有限几类。

5. User-Agent 维度要谨慎

有些站点会根据 User-Agent 返回不同 HTML。

如果加:

Vary: User-Agent

缓存可能为大量浏览器版本生成大量副本。

这会造成缓存碎片化。

更推荐的方式通常是响应式设计,或者在 CDN 层把设备类型归一化成少数几个维度。

6. Vary 和 Cache-Control 的关系

Cache-Control 决定响应能不能缓存、缓存多久、是否必须再验证。

Vary 决定可缓存响应要按哪些请求头区分版本。

二者配合使用。

例如:

Cache-Control: public, max-age=3600
Vary: Accept-Encoding

这表示响应可被共享缓存保存 3600 秒,但缓存副本要按压缩能力区分。

7. 常见误区与追问

  • 误区:Vary 是控制缓存时间的。 缓存时间主要由 Cache-Control 等头控制,Vary 控制缓存变体维度。
  • 误区:设置更多 Vary 一定更安全。 维度太多会降低命中率,甚至让缓存几乎不可复用。
  • 误区:压缩响应不需要 Vary。 压缩算法不同会影响响应体,通常需要 Vary: Accept-Encoding
  • 追问:Vary: * 表示什么? 表示响应依赖未列明因素,共享缓存通常不能复用该响应。
  • 追问:漏掉 Vary 会怎样? 可能把某类客户端的响应错误发给另一类客户端。
  • 追问:Vary 和 CDN 有什么关系? CDN 会用它构造缓存 key,影响正确性和命中率。

8. 加强记忆

记住:Cache-Control 管时间,Vary 管版本。

回答 Vary 时一定带上“正确性”和“命中率”这对权衡。