root指令仅负责URI到磁盘路径的拼接定位,不参与缓存;expires或Cache-Control才控制缓存,但必须在root映射正确、返回200响应的location中才能生效,否则404/403导致缓存完全失效。

root 指令本身不负责缓存,它只管“文件在哪”;真正起缓存作用的是 expires 或 add_header Cache-Control。但二者必须配合正确——路径映射对了,缓存才能生效。配错 root,资源 404,缓存就完全失效。
✅ 正确理解 root 的作用方式
root 是拼接型路径定位:
- 配置
root /var/www/static; - 请求
/css/main.css - Nginx 实际查找:
/var/www/static/css/main.css(URI 全路径追加到 root 后)
⚠️ 常见误区:
- 认为
location /css/ { root /var/www; }会去找/var/www/main.css→ 错!实际是/var/www/css/main.css - 在
root路径末尾多写/(如root /var/www/;)一般不影响,但和alias混用时易引发路径重复
✅ 缓存指令必须落在能返回静态内容的 location 中
只有成功读取到文件并返回 200 响应,expires 或 Cache-Control 才会被写入响应头。
若因 root 配置错误导致 404 或 403,缓存策略根本不会触发。
推荐写法(带校验逻辑):
location ~* \.(js|css|png|jpg|webp|woff2|svg|ico)$ {
root /opt/myapp/dist; # 确保该目录下真有对应文件
expires 1y;
add_header Cache-Control "public, immutable";
}验证是否生效:
- 访问
https://your.site/js/app.abc123.js - 查看浏览器开发者工具 → Network → Response Headers → 应有
Cache-Control: public, immutable和Expires: ... - 若没有,先检查 Nginx error log 是否报
open() "/opt/myapp/dist/js/app.abc123.js" failed (2: No such file or directory)
✅ 静态资源缓存最佳实践组合
针对不同资源类型,建议分层配置:
-
带哈希名的构建产物(如
main.a1b2c3.js)location ~* \.[a-f0-9]{8,}\.(js|css|png|jpg|webp|woff2|svg)$ { root /opt/myapp/dist; expires 1y; add_header Cache-Control "public, immutable" always; } -
普通静态资源(无哈希,可能更新)
location ~* \.(ico|gif|jpeg|png|svg|eot|ttf|woff|woff2)$ { root /opt/myapp/static; expires 7d; add_header Cache-Control "public, max-age=604800" always; } -
HTML 文件不缓存(或短缓存)
location / { root /opt/myapp/dist; index index.html; # 不加 expires,或仅设 1s 防止旧 HTML 被长期缓存 add_header Cache-Control "no-cache, must-revalidate" always; }
⚠️ 注意:
add_header ... always可确保即使返回 304、404 也携带头(部分场景需此行为),而expires默认只对 2xx/3xx 生效。
✅ 权限与路径排查要点
-
root目录需被nginx用户(通常是www-data或nginx)读取 - 执行
ls -ld /opt/myapp/dist和ls -l /opt/myapp/dist/js/确认权限为r-x(目录)和r--(文件) - 若用 SELinux,可能需
setsebool -P httpd_read_user_content 1 - 日志中出现
(13: Permission denied)就说明权限不足,不是缓存配置问题
不复杂但容易忽略。


















