nginx可通过expires max、资源指纹与immutable响应头实现“永久缓存”效果:对带哈希的静态资源(如app.a1b2c3.js)设expires max并添加cache-control "public, immutable, max-age=31536000",确保强缓存命中且自动更新;须用正则或前缀精准匹配静态路径,避免误缓存html等动态内容。

“永久缓存”在 HTTP 协议中并不存在,但 Nginx 可通过 expires max 配合资源指纹(如文件名哈希)和 immutable 响应头,实现接近“永久可用、自动更新”的强缓存效果。核心不是让时间无限长,而是让缓存足够久、且内容变更时旧缓存自然失效。
精准匹配静态资源路径
必须避免泛匹配误伤动态内容。推荐两种方式:
- 用正则匹配常见静态后缀(忽略大小写):
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2|ttf|eot|webp)$ { ... } - 若静态资源统一放在特定目录(如
/static/或/assets/),优先用前缀匹配:location ^~ /static/ { ... }—— 性能更高,无正则开销
切勿在 location / 或 location ~ \.html$ 中设置 expires,否则 HTML 被强缓存会导致用户看不到更新。
差异化设置缓存策略
缓存时长取决于资源是否带内容哈希(如 app.a1b2c3.js),而非单纯看后缀:
- 带哈希的 JS/CSS/字体/WebP:内容不变 URL 就不变,可设为长期缓存
expires max;(等价于 1 年,Nginx 内部通常设为 2037 年末) - 图片、图标、SVG 等稳定但无哈希的资源(如
logo.png):expires 30d; - 未版本化的通用资源(如
config.json):expires 1h;或expires 1d;,降低更新延迟风险 - HTML、PHP、JSON 接口等动态内容:
expires epoch;或expires -1;,强制不缓存
必须补全 Cache-Control 并启用 immutable
expires 只生成基础响应头,现代浏览器更依赖 Cache-Control,且需语义完整:
- 对带哈希资源,务必合并写成一条:
add_header Cache-Control "public, immutable, max-age=31536000"; -
immutable是关键——它告诉浏览器该资源在生命周期内不会变更,F5 刷新也不会发If-None-Match等条件请求,大幅提升重复访问性能 - 不要分开写多个
add_header,否则会覆盖;max-age值必须与expires时间逻辑一致(如1y ≈ 31536000秒)
验证缓存是否真正生效
配置完成后不能直接上线,要逐层确认:
- 运行
nginx -t检查语法,再nginx -s reload重载 - 用
curl -I https://your.site/app.a1b2c3.js查看响应头,确认同时存在:Cache-Control: public, immutable, max-age=31536000Expires: [日期远在2037年] - 打开 Chrome DevTools → Network → 刷新页面,观察静态资源状态码:
首次加载为200;再次刷新显示200 (from memory cache)或200 (from disk cache)即表示强缓存命中
不复杂但容易忽略











