gzip_vary on是保障缓存正确性的必要配置,它通过自动添加Vary: Accept-Encoding响应头,使缓存系统能区分压缩与未压缩响应;仅在实际压缩时添加该头,避免误判变体依据,推荐在http或server块中启用gzip on和gzip_vary on。

gzip_vary 不是可选的“优化开关”,而是保障缓存正确性的必要配置。它通过在响应头中插入 Vary: Accept-Encoding,让浏览器、CDN 和反向代理明确知道:同一 URL 的响应内容会因客户端是否声明支持 gzip 而不同。若缺失该头,缓存系统可能把压缩版错发给不支持解压的老设备或工具,造成页面空白、JS 执行失败或样式丢失。
为什么必须开启 gzip_vary on
启用 gzip 后,Nginx 对同一个请求路径可能返回两种完全不同的字节流:
- 客户端未带
Accept-Encoding: gzip→ 返回明文响应 - 客户端声明支持 gzip → 返回 gzip 压缩流
如果没有 Vary: Accept-Encoding,缓存层(如 CDN、Nginx 自身 proxy_cache、甚至浏览器)会把这两个响应当作“完全相同”来存储和复用。结果就是:某台手机缓存了压缩版,下次用不支持 gzip 的微信内置浏览器访问时,直接拿到乱码二进制数据。
正确配置方式(推荐且足够)
只需在 http 或 server 块中启用两项:
-
gzip on;—— 开启压缩功能 -
gzip_vary on;—— 自动添加Vary: Accept-Encoding响应头
无需手动 add_header Vary Accept-Encoding,因为 gzip_vary on 已由 Nginx 内部逻辑精准控制:仅当实际执行了压缩时才添加该头;未压缩响应则不加——这避免了缓存系统误判“所有响应都依赖 Accept-Encoding”。
哪些情况可以关闭 gzip_vary?
关闭 gzip_vary 是高风险操作,仅限以下三类严格可控场景:
- CDN 全面接管压缩逻辑(如 Cloudflare 启用 Brotli + Auto Minify),且保证所有终端收到统一压缩响应
- 全站静态资源已预生成
.gz文件,并启用gzip_static on,Nginx 不再做动态压缩 - 服务直连终端,中间无任何缓存(如内网 API 网关、本地开发代理)
只要涉及 CDN、反向代理或浏览器多端访问,一律保持 gzip_vary on。
验证是否生效
用 curl 模拟支持 gzip 的客户端发起请求:
curl -I -H "Accept-Encoding: gzip" https://yoursite.com/main.js成功响应应同时包含:
Vary: Accept-EncodingContent-Encoding: gzip
这两项共同表明:Nginx 正确识别了压缩能力,并向缓存系统声明了响应变体依据——这是 HTTP 缓存一致性最基础也最关键的信号。


















