gzip_vary的核心作用是让缓存系统区分压缩版和未压缩版响应,通过添加Vary: Accept-Encoding头使缓存键包含Accept-Encoding值,避免不支持压缩的客户端收到乱码。

gzip_vary 的核心作用,是让缓存系统能区分“压缩版”和“未压缩版”响应。它不直接提升压缩效率,而是解决多版本内容被错误混用的问题——尤其在 CDN、反向代理或浏览器本地缓存场景下,避免把 gzip 压缩后的内容错发给不支持压缩的客户端。
为什么需要区分两个缓存版本
当一个资源(比如 /style.css)同时被两类用户请求时:
- 用户 A 的浏览器发送
Accept-Encoding: gzip→ Nginx 返回压缩内容,Content-Encoding: gzip - 用户 B 的浏览器没发该头(或只支持
br)→ Nginx 返回原始明文内容
如果没有 Vary: Accept-Encoding,缓存层(如 CDN 或 nginx 自身 proxy_cache)可能把 A 的压缩响应当成通用结果,直接返回给 B —— 导致 B 收到乱码或解析失败。
gzip_vary 如何协同缓存工作
开启 gzip_vary on 后,Nginx 自动在响应头中添加:
Vary: Accept-Encoding
这相当于告诉所有中间缓存:“请把 Accept-Encoding 的值也纳入缓存 key 计算”。也就是说:
-
GET /style.css+Accept-Encoding: gzip→ 缓存 key 包含 "gzip" -
GET /style.css+Accept-Encoding: identity→ 缓存 key 包含 "identity" - 两个请求走的是完全不同的缓存条目,互不干扰
什么时候可以关掉 gzip_vary
关闭 gzip_vary off 并非绝对错误,但需满足特定条件:
- 你完全控制前端缓存(比如自建反向代理),且明确做了
Accept-Encoding感知的缓存分片 - 使用预压缩(
gzip_static on)并配合add_header Vary Accept-Encoding手动控制 - CDN 厂商已内置对 gzip 的智能缓存分离(如 Cloudflare 自动处理,无需你加 Vary)
多数中小站点建议保持默认开启,避免因缓存复用引发兼容性问题。
验证是否生效的关键点
只需检查任意一个被压缩的响应头是否同时包含:
Content-Encoding: gzipVary: Accept-Encoding
二者缺一不可。若只有前者,说明 gzip 已启用但缓存隔离机制未激活;若只有后者,说明 Vary 头存在但实际未压缩(可能是 gzip_types 未覆盖该 MIME 类型)。


















