Nginx 中 try_files + @named 是实现“本地优先、兜底转发”的标准方式,命名 location 以@开头,仅能被显式调用,不参与匹配,不可含正则或变量,通常封装 proxy_pass 等终结指令。

直接用 try_files 触发命名 location 跳转,是 Nginx 实现“本地优先、兜底转发”的标准做法。它不产生 HTTP 重定向,全程对客户端透明,适合 SPA 路由、API 回退、静态缓存穿透等场景。
命名 location 的作用和限制
以 @ 开头的 location(如 @backend)不是普通匹配块,它不参与常规请求匹配,只能被 try_files、error_page 或 rewrite ... last 显式调用。它不能包含正则、不能带变量、也不能嵌套其他指令块——只用来封装一组处理逻辑,比如代理、重写或返回。
- 必须写在 server 或 http 块内,与普通 location 平级
- 不能用
root或alias定义路径,因为不处理文件查找 - 里面通常只放
proxy_pass、return、rewrite等终结型指令
try_files + @named 的典型写法
最后一项必须是 @xxx 形式,前面的项用于本地检查(文件、目录),全部失败后才跳转:
location / {
root /var/www/app;
try_files $uri $uri/ @fallback;
}
<p>location @fallback {
proxy_pass <a href="https://www.php.cn/link/92cdc3666b7883ebeed2973e70725bb1">https://www.php.cn/link/92cdc3666b7883ebeed2973e70725bb1</a>;
proxy_set_header Host $host;
}</p>
含义:先找 /var/www/app/xxx 文件 → 再找 /var/www/app/xxx/ 目录 → 都不存在就跳进 @fallback,由它把请求原样转发给后端服务。
常见错误配置及后果
以下写法看似合理,但实际会报错或行为异常:
-
try_files $uri @proxy https://api.example.com—— 最后一项不是@或/开头,Nginx 启动失败 -
location @proxy { alias /remote/; }——alias在命名 location 中无效,会被忽略 -
try_files $uri @proxy; location @proxy { try_files /tmp/cache$uri =404; }—— 命名 location 内再用try_files是允许的,但要注意路径是否真实存在,否则可能返回 500
配合前端 SPA 的完整示例
Vue/React 项目启用 history 模式时,需确保所有非静态资源都落到 index.html,但又不想让 API 请求也被重写:
location / {
root /var/www/spa;
try_files $uri $uri/ @rewrites;
}
<h1>静态资源优先走本地</h1><p>location ~* .(js|css|png|jpg|gif|ico|svg)$ {
root /var/www/spa;
expires 1y;
add_header Cache-Control "public, immutable";
}</p><h1>API 请求交给后端,其他全归前端路由接管</h1><p>location @rewrites {
if ($uri ~ ^/api/) {
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
break;
}
proxy_pass <a href="https://www.php.cn/link/1ce5e897cda6aeb211dffe8d514f4365">https://www.php.cn/link/1ce5e897cda6aeb211dffe8d514f4365</a>; # 或直接 return 200 /index.html;
}</p>
注意:if 在 location 中可用,但仅限简单判断;更推荐用两个独立的 @ 块加 try_files 分流。











