Nginx 1.3.3+ 默认启用 etag on,自动为静态文件生成ETag响应头;其行为受etag指令和gzip_static模块影响,不支持proxy_pass等动态响应,禁用需用etag off。

在 Nginx 源码编译安装时,ETag 功能默认是启用的,但它的行为由两个关键模块控制:核心模块中的 etag 指令和 http_gzip_static_module(或第三方模块如 ngx_http_gzip_static_module)对压缩文件 ETag 的处理逻辑。它本身没有单独的“ETag 指令”可配置,而是通过 etag on|off 控制是否输出 ETag 响应头,且该指令仅作用于静态文件(非 proxy_pass 或 fastcgi 等后端响应)。
确认 etag 指令是否可用及默认状态
Nginx 1.3.3+ 版本起,etag 指令已内置在核心模块中,无需额外编译参数开启。默认值为 on,即自动为静态文件(如 .html、.css、.js、图片等)生成并输出 ETag 头。
- 可通过
nginx -V 2>&1 | grep -o with-http_gzip_static_module查看是否启用了 gzip_static 模块(影响 .gz 文件的 ETag 行为) - 在配置中添加
etag off;可全局禁用,但无法细粒度控制某类文件 -
etag指令只能出现在http、server或location块中,不支持在 if 或 rewrite 中使用
源码编译时影响 ETag 行为的关键参数
虽然 etag 指令本身无需编译开关,但以下编译选项会间接改变 ETag 的实际表现:
-
--with-http_gzip_static_module:启用后,Nginx 会优先服务.gz文件(如style.css.gz),并为其生成独立 ETag(基于 .gz 文件元数据)。若未启用,Nginx 不识别 .gz 文件,也不会为它们生成 ETag -
--without-http_gzip_module:禁用 gzip 压缩模块,不影响静态 ETag,但可能使前端缓存策略混乱(例如浏览器收到未压缩内容却缓存了带 gzip ETag 的响应) - 不推荐手动修改源码(如
src/http/ngx_http_core_module.c中的ngx_http_set_etag函数),易引发兼容性问题且升级困难
验证与调试 ETag 输出是否生效
部署后需确认 ETag 是否按预期工作:
- 用
curl -I https://example.com/style.css查看响应头中是否有ETag:字段(值通常为"<inode>-<mtime>-<size>"</size></mtime></inode>格式) - 若启用了 gzip_static,对
/style.css请求同时存在style.css和style.css.gz,则访问前者返回原始文件 ETag,后者返回 .gz 文件的 ETag(二者不同) - 注意:当启用
gzip_vary on且后端动态生成内容时,ETag 不会自动添加——因为etag仅对ngx_http_static_module处理的磁盘文件生效
常见误操作与建议
很多用户试图通过编译参数“开启 ETag”,其实属于方向错误:
- 不要尝试添加
--with-etag-module—— Nginx 官方没有这个模块,也不存在对应参数 - 避免在
location ~ \.php$或proxy_pass区域写etag on,它不会生效,后端响应的 ETag 应由上游服务控制 - 若需对代理内容统一加 ETag,应使用
add_header ETag ...手动设置(但会覆盖上游 ETag,慎用) - 生产环境建议保持
etag on默认,配合expires或Cache-Control使用,提升缓存命中率


















