可通过嵌套 location 实现静态资源差异化缓存与动态请求安全转发:在 /static/ 等前缀下嵌套正则匹配不同后缀并设置独立 expires;动态请求由 location / + try_files $uri $uri/ @backend 统一兜底;优先用 alias 避免 root 拼接歧义;需验证响应头与状态码是否符合预期。

可以通过 location 嵌套,在同一个 server 块内既服务静态资源(带差异化缓存策略),又把未命中静态路径的请求安全转发给后端应用,关键在于匹配顺序、作用域隔离和缓存粒度控制。
用嵌套 location 区分文件类型并设置不同缓存时长
在主静态路径 location 内部,再定义子 location 匹配具体后缀,避免所有静态资源统一过期时间不合理的问题。比如:
- /static/ 作为根静态入口,指定 root 和默认缓存
- 内部嵌套 ~* \.(css|js)$ 子块,单独设为 7 天缓存
- 再嵌套 ~* \.(jpg|png|gif)$,设为 90 天缓存
- 子 location 中的 expires 指令会覆盖外层,且只作用于匹配到的文件
确保动态请求不被静态规则拦截
静态资源 location 应明确限定路径前缀(如 /static/、/images/),避免使用泛匹配(如 / 或 ^~\.)覆盖全部请求。真正需要转发的动态路径应由独立的、优先级更低的 location / 捕获,并配合 try_files 或 if 判断是否真实存在文件:
- 写法一(推荐):location / { try_files $uri $uri/ @backend; },先查静态,不存在则跳转到 @backend
- 写法二:用 if (!-e $request_filename) { proxy_pass http://app; },但需注意 if 在 location 中有局限性,仅适用于简单判断
- 不要让静态 location 的正则(如 ~ \.html$)意外匹配 API 路径(如 /api/v1/user.html)
注意嵌套中的 root 与 alias 使用差异
嵌套 location 里若用 root,路径是拼接关系;用 alias 是替换关系,容易出错:
- location /static/ { root /var/www; } → 请求 /static/js/app.js 实际找 /var/www/static/js/app.js
- location /static/ { alias /var/www/assets/; } → 同样请求实际找 /var/www/assets/js/app.js(/static/ 被替换成 alias 值)
- 嵌套中混用 root 和 alias 可能导致路径错位,建议统一风格,静态资源目录优先用 alias 避免拼接歧义
验证缓存头与转发行为是否生效
部署后必须检查响应头和状态码,确认逻辑按预期执行:
- 访问 /static/css/main.css,响应头应含 Cache-Control: max-age=604800(7天)
- 访问 /static/images/logo.png,应返回 Cache-Control: max-age=7776000(90天)
- 访问 /api/users,应返回后端响应,且响应头不含静态缓存字段,Status 为 200(非 304)
- 访问一个不存在的静态路径(如 /static/missing.js),若配置了 try_files,应返回 404;若 fallback 到 @backend,则需确认后端是否处理该路径










