最清晰可控的nginx缓存配置是按文件后缀分组设置独立location块,统一用add_header cache-control(带always参数),禁用expires混用;长期资源设1年+immutable,普通静态资源设1周,html/动态内容用no-cache+验证机制。

直接按文件后缀配置缓存是最清晰、最可控的方式。Nginx 不支持在单个 location 中用 if 判断多种后缀,也不推荐混用 expires 和 add_header Cache-Control——容易覆盖失效。正确做法是为不同后缀组分别定义独立的 location 块,每个块只做匹配 + 缓存头设置两件事。
区分后缀分组,各自设置缓存策略
把静态资源按更新频率和使用场景归类,再对应设置缓存时长与语义:
-
长期稳定资源(带哈希名):如
.js、.css、.png等文件名含内容哈希(如app.8a2b3c.js)的,可设为 1 年 +immutable - 普通静态资源:如未带哈希的图片、字体、图标等,设为 1 周或 30 天较稳妥
-
HTML/JSON/动态入口:禁用长期缓存,用
no-cache或must-revalidate,依赖 ETag 或 Last-Modified 验证
location 块写法要规范
每个后缀组用一个独立的正则 location,注意写法细节:
- 用
~*开头,忽略大小写(.JPG和.jpg都能匹配) - 正则中不要加
/开头或结尾,避免误匹配路径 - 不写
proxy_pass或重写逻辑,只专注响应头控制 - 加上
always参数,确保 304 响应也携带缓存头
示例:
location ~* \.[a-f0-9]{8,}\.(js|css|png|jpg|gif|svg|woff2)$ {
add_header Cache-Control "public, max-age=31536000, immutable" always;
}
location ~* \.(png|jpg|jpeg|gif|svg|ico|woff2|ttf|eot)$ {
add_header Cache-Control "public, max-age=604800" always;
}
location ~* \.(html|htm|php|json|xml)$ {
add_header Cache-Control "private, no-cache, must-revalidate" always;
}避免常见陷阱
几个高频出错点需特别注意:
- 别混用 expires 和 add_header Cache-Control:后者会完全覆盖前者;统一用 add_header 更可靠
- 不要在一个 location 里穷举所有后缀再 if 判断:Nginx 的 if 在 location 中行为不可靠,易引发缓存漏配
-
HTML 文件不能简单设 expires -1:要配合
no-cache+ 验证机制,否则可能跳过协商缓存 -
动态后缀如 .php 默认不缓存:即使返回静态内容,也要显式用
proxy_no_cache或proxy_cache_bypass控制
补充:反向代理级缓存可叠加使用
如果 Nginx 同时作为反向代理,可在上述基础上叠加 proxy_cache,但要注意缓存键设计:
- 对静态资源,建议关闭
proxy_cache,只用浏览器缓存,减少磁盘 IO - 对 API 或模板页等动态内容,启用
proxy_cache,并用proxy_cache_key排除用户敏感参数(如 token、session_id) - 加
add_header X-Cache-Status $upstream_cache_status方便排查命中情况











