开启ETag需Nginx 1.17.5+版本支持内容哈希生成,配置etag on并禁用add_header覆盖、避免if-modified-since混用,配合Cache-Control实现高效缓存验证。

开启 ETag 可以让浏览器对静态资源进行更精准的缓存验证,减少不必要的 304 响应开销,但 Nginx 默认的 etag on 行为在某些场景下反而影响效率或与后端不一致。要真正发挥 ETag 作用,需结合文件内容(而非仅修改时间)生成,并配合正确的缓存头策略。
确认 Nginx 版本支持内容哈希型 ETag
Nginx 1.17.5+ 原生支持基于文件内容生成 ETag(通过 etag on + file_cache 机制),旧版本(如 1.16.x)仅支持基于 mtime/inode 的弱 ETag(W/"..." 格式),无法准确反映内容变更。建议升级至 1.18.0 或更高稳定版。
启用强 ETag 并禁用易冲突的配置
在 server 或 location 块中添加以下配置:
-
开启 ETag:
etag on;(Nginx 1.17.5+ 默认即为内容哈希;旧版本无效) -
关闭可能覆盖 ETag 的指令:确保未设置
add_header ETag ...或more_set_headers "ETag: ...",否则会强制覆盖 Nginx 自动生成的值 -
避免与 if-modified-since 混用冲突:不要在同个 location 中同时依赖
if_modified_since和 ETag 验证逻辑,Nginx 会优先使用 If-None-Match 头做 ETag 匹配
搭配 Cache-Control 实现高效缓存协同
ETag 单独存在意义有限,需配合合理缓存策略:
- 对 JS/CSS/图片等长期不变资源,设
Cache-Control: public, max-age=31536000, immutable,浏览器跳过条件请求,ETag 不触发 - 对可能更新但不频繁的资源(如带哈希名的 bundle),用
Cache-Control: public, max-age=3600,让 ETag 在一小时内生效,提升验证精度 - 禁用
expires指令与Cache-Control混用,防止头冲突
验证 ETag 是否生效且内容相关
部署后,用 curl 检查响应头:
curl -I https://example.com/style.css观察是否返回类似:
ETag: "6a8e2c4d3f1b2a8c9d0e1f2a3b4c5d6e"再修改文件内容并重载(不重启),再次请求,确认 ETag 值已变化 —— 若不变,说明仍走 mtime 模式或文件未被重新读取(可加 open_file_cache off; 临时排除缓存干扰)。

















