nginx中压缩资源不单独设缓存生命周期,而是复用原始资源的缓存策略;关键在于确保cache-control/expires正确生效、vary: accept-encoding存在,并避免压缩与缓存头配置冲突。

在 Nginx 中,压缩资源(如 gzip 或 brotli 压缩后的 CSS、JS、HTML)本身不单独设置“压缩缓存生命周期”,而是复用其原始资源的缓存策略。关键在于:**压缩是传输编码(transfer encoding),不是内容类型变更;缓存控制应作用于资源本身,而非压缩形式**。只要响应头中的 Cache-Control 或 Expires 正确生效,无论是否启用 gzip/brotli,浏览器和代理都会按同一规则缓存该资源。
确保压缩资源继承正确缓存头
很多问题源于压缩后缓存头被意外覆盖或丢失。需确认以下两点:
- 压缩指令(
gzip on或brotpi on)必须放在location块之外(通常在http或server级),避免与缓存头配置冲突 - 缓存头(如
expires或add_header Cache-Control)应写在压缩启用之后,且不被子块重复覆盖 - 若使用
add_header,注意它不会覆盖已存在的同名头,但expires指令会自动设置Expires和Cache-Control,更可靠
静态压缩资源的推荐配置
针对已预压缩的文件(如 style.css.gz),需显式匹配并设缓存:
- 启用
gzip_static on或brotpi_static on,让 Nginx 优先返回预压缩文件 - 为对应后缀单独配置缓存,例如:
add_header Content-Encoding gzip;
add_header Cache-Control "public, max-age=31536000";
add_header Vary Accept-Encoding;
}
动态压缩时的缓存一致性要点
当 Nginx 动态压缩后端响应(如 PHP 返回的 HTML),要防止缓存错乱:
- 务必添加
add_header Vary Accept-Encoding;—— 这告诉缓存系统:同一 URL 的响应可能因客户端是否支持 gzip 而不同,避免未压缩版本被误返回给支持压缩的客户端 - 若启用了
proxy_cache,缓存键(proxy_cache_key)中应包含$http_accept_encoding,否则 gzip 和非 gzip 响应可能共用一个缓存项 - 示例缓存键:
proxy_cache_key "$scheme$request_method$host$request_uri$http_accept_encoding";
验证是否生效
通过 curl 检查响应头即可确认:
-
curl -I -H "Accept-Encoding: gzip" https://yoursite.com/app.js→ 查看Content-Encoding: gzip和Cache-Control是否同时存在 - 对比无压缩请求:
curl -I -H "Accept-Encoding:" ...→ 确认Vary头存在,且缓存头一致 - 浏览器开发者工具 Network 标签中,检查资源的
memory cache或disk cache状态及age字段











