最常用方式是用多个location ~*块按后缀匹配并设置expires与add_header Cache-Control,仅控制浏览器缓存;需区分带哈希与不带哈希资源,优先为指纹文件设1年+immutable,普通静态资源设1周,HTML等动态内容禁用强缓存。

Linux 下用 Nginx 的 location 按文件后缀设置缓存,核心是匹配后缀、控制响应头,**只影响浏览器缓存行为,不涉及 Nginx 本地磁盘缓存**。这是最常用也最容易上手的方式。
匹配后缀并设置 expires 和 Cache-Control
直接在 server 块内添加多个 location ~* 块,用正则匹配后缀,再用 expires 和 add_header 设置缓存策略:
-
expires自动生成Expires和Cache-Control: max-age=...头,推荐优先使用 -
add_header Cache-Control ... always可补充或覆盖(如加immutable),always确保即使返回 304 或错误码也生效 - 匹配顺序很重要:Nginx 会按配置顺序查找第一个匹配的
location,建议把更具体的写在前面
示例配置:
location ~* \.[a-f0-9]{8,}\.(js|css|png|jpg|gif|svg|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable" always;
}
<p>location ~* .(js|css|png|jpg|jpeg|gif|svg|ico|woff2|ttf|eot)$ {
expires 1w;
add_header Cache-Control "public" always;
}</p><p>location ~* .(html|htm|php|json|xml|txt)$ {
add_header Cache-Control "private, no-cache, must-revalidate" always;
}</p>
区分“带哈希”与“不带哈希”的静态资源
现代前端构建(如 Webpack/Vite)常给 JS/CSS 文件名注入哈希值(如 main.a1b2c3d4.js),这类资源内容不变时 URL 就不变,适合长期缓存;而普通 main.js 则可能被覆盖更新,需更短缓存周期。
- 第一段正则
\.[a-f0-9]{8,}\.专门捕获含 8 位以上哈希的文件,设为 1 年 +immutable - 第二段匹配所有常见静态后缀,但不含哈希逻辑,设为 1 周,避免用户卡旧版
- 第三段对 HTML/PHP 等动态内容禁用强缓存,强制每次校验
注意几个关键细节
这些点看似小,但线上容易出问题:
-
expires不会覆盖后端已设置的Cache-Control。如果 PHP 或 Node.js 接口本身返回了no-cache,Nginx 的expires就无效 - 不要对
.html盲目设expires 1y。哪怕用了版本号(如/v2/index.html),只要路径没变,浏览器就不会重发请求 - 图片类(
.png/.jpg)可设较长缓存,但 SVG 图标若频繁修改,建议走哈希命名或缩短周期 - 字体文件(
.woff2/.ttf)通常稳定,设 1 年合理;.ico文件极小且极少改动,也可设长周期
验证是否生效
配置保存后,执行:
-
sudo nginx -t检查语法 -
sudo systemctl reload nginx重载配置 - 用浏览器开发者工具 → Network 标签页,查看目标资源的响应头,确认有
Cache-Control和Expires - 注意:首次访问是
200 OK,第二次 F5 若看到200 from disk cache或304 Not Modified,说明缓存已起作用











