最稳妥的缓存配置是按文件后缀分类设置:JS/CSS/字体/WebP等带哈希资源设1年强缓存+immutable;图片设30天;HTML/PHP等动态页禁用强缓存;避免在根location统一设缓存或仅依赖Expires。

直接在 location 块中用 expires 指令配合 add_header Cache-Control,按后缀精准控制缓存时长——不是越长越好,而是匹配文件是否带版本哈希、更新频率和业务发布节奏。
用 ~* 正则匹配主流后缀,分类配置
这是最常用也最稳妥的方式,避免误伤 HTML 或接口响应。每类资源单独写一个 location,顺序无关紧要(Nginx 正则匹配无优先级冲突):
-
JS/CSS/字体/WebP 等带哈希名的资源:设一年强缓存 + immutable,确保内容变更即刷新缓存
location ~* \.(js|css|woff2?|ttf|eot|svg|webp)$ {<br> expires 1y;<br> add_header Cache-Control "public, immutable, max-age=31536000";<br>} -
图片(jpg/png/gif 等):设 30 天,兼顾 CDN 分发与运营更新灵活性
location ~* \.(jpg|jpeg|png|gif|bmp|ico)$ {<br> expires 30d;<br> add_header Cache-Control "public, max-age=2592000";<br>} -
HTML/PHP/XML 等动态或入口页:禁用强缓存,强制每次校验
location ~* \.(html|htm|php|xml|json)$ {<br> expires -1;<br> add_header Cache-Control "no-cache, must-revalidate, max-age=0";<br>}
不推荐也不安全的写法
这些配置看似简洁,实则风险高,容易导致用户看到过期页面或接口返回被缓存:
- 在
location /里统一写expires 1h—— 会把所有请求(含 API、登录页)都缓存 - 用
location ~ \.html$设置长缓存 —— 静态生成的 HTML 可能没哈希,更新后用户刷不出来 - 只写
expires不补Cache-Control—— 浏览器行为不一致,部分旧版客户端忽略 Expires
必须验证的两个关键点
配置完别急着 reload,先确认响应头是否真正生效:
- 用
curl -I https://yoursite.com/app.a1b2c3.js查看是否有Expires和Cache-Control字段,且值符合预期 - 打开 Chrome DevTools → Network → 刷新页面,找一个 JS 文件,看 Size 列是否显示 from memory cache 或 from disk cache
- 执行
nginx -t通过后再nginx -s reload,避免语法错误导致服务中断
小提醒:缓存策略依赖文件命名方式
JS/CSS 设 1 年缓存的前提是文件名含内容哈希(如 main.f3a7b2.js)。如果用固定名(如 app.js),哪怕加了 immutable,用户也无法感知更新——此时应降为短缓存(比如 1h),或配合 ETag + Last-Modified 让浏览器发起条件请求。


















