静态资源缓存时长由Nginx通过Cache-Control响应头分级控制:指纹化资源设1年+immutable,普通静态资源设30天,HTML设no-cache或no-store;优先用add_header而非expires,并确保状态码、请求方法及无Set-Cookie等前提满足。

静态资源响应缓存时长主要由客户端(浏览器)控制,Nginx 通过设置 Cache-Control 或 Expires 响应头来告诉浏览器“能缓存多久、是否可共享、是否允许验证复用”。关键不是只设一个时间,而是按资源稳定性分级配置,并优先使用 Cache-Control。
按文件类型区分缓存策略
不同静态资源更新频率差异大,统一设 1 年或 1 天都不合理。推荐在 location 块中按扩展名匹配并差异化设置:
-
带哈希指纹的资源(如
app.a1b2c3.js、style.f4e5d6.css):内容不变则文件不变,可设极长期 + 不可变标记add_header Cache-Control "public, max-age=31536000, immutable" always; -
普通图片、字体、图标(
.png、.jpg、.woff2):变动较少,设 30 天较稳妥add_header Cache-Control "public, max-age=2592000" always; -
HTML 文件(
.html):通常不建议长期缓存,尤其不含版本号时add_header Cache-Control "no-cache, must-revalidate" always;或直接禁用缓存:add_header Cache-Control "no-store" always;
优先用 add_header 而非 expires
expires 指令会同时生成 Expires 头和基础版 Cache-Control: max-age=...,但无法添加 public、immutable 等关键指令。而 add_header 更灵活、语义清晰:
- 它明确表达缓存意图(如是否允许 CDN 缓存、是否跳过验证)
- 配合
always参数可覆盖上游(如 PHP-FPM 或反向代理)已设的同名头 - 避免因多个模块重复设置导致头冲突或覆盖失效
注意缓存生效的前提条件
即使配置了 Cache-Control,缓存也可能不生效。需确认以下几点:
- 响应状态码必须是可缓存的(如
200、302、304),206(分片下载)和4xx/5xx默认不缓存 - 请求方法需为
GET或HEAD(Nginx 默认只缓存这两类) - 响应头中不能有
Set-Cookie(除非显式用proxy_ignore_headers Set-Cookie忽略) - 若资源走的是
root+try_files,而非proxy_pass,则 Nginx 不会自动加Cache-Control—— 必须手动add_header
验证配置是否生效
用 curl -I 查看响应头,确认目标资源返回了预期的缓存指令:
curl -I https://yoursite.com/static/main.js- 检查输出中是否有类似
Cache-Control: public, max-age=31536000, immutable - 同时观察
Expires是否与max-age逻辑一致(如max-age=31536000对应约 1 年后的时间戳)


















