Nginx 中 location @name 定义命名位置,仅用于内部重定向(如 error_page、try_files),不响应外部请求,自动视为 internal,不可直接访问,核心价值是解耦逻辑与路径、集中复用配置。

在 Nginx 配置中,location @name 定义的是命名位置(named location),它不响应外部请求,只供内部重定向(如 error_page、try_files 或 rewrite ... break)使用。它的核心价值在于解耦逻辑与路径,实现清晰、高效的内部跳转。
命名位置的本质是内部跳转锚点
不同于普通 location /path,@name 不匹配 URI 字符串,也不出现在访问日志的请求行中。它纯粹是配置内的“标签”,仅能通过 internal 方式触发:
-
error_page 404 @notfound;→ 发生 404 时静默跳转到@notfound -
try_files $uri @php;→ 文件不存在时交由@php处理 -
rewrite ^/old/(.*)$ /new/$1 break;后接proxy_pass http://backend;,但若想复用一组代理逻辑,可改用rewrite ^/old/(.*)$ /new/$1 break; proxy_pass http://backend;→ 更推荐封装为@backend,统一维护
必须配合 internal 指令或内部指令使用
直接访问 http://example.com/@api 会返回 404 —— 因为命名位置默认禁止外部访问。这是安全设计,不是 bug:
- 不需要手动加
internal;到@name块里(Nginx 会自动视为 internal) - 但若误写成
location /@api { ... }(带斜杠),就变成普通 location,可能被外部访问,失去命名位置意义 - 常见错误:在
@name中写return 200 "ok";却期望浏览器直接访问它 → 实际必须通过error_page或try_files触发
典型高效用法:集中处理后端路由逻辑
避免重复配置 proxy 相关参数,把通用代理行为抽象为命名位置:
upstream app {
server 127.0.0.1:8000;
}
<p>server {
listen 80;
server_name example.com;</p><pre class="brush:php;toolbar:false;"># 静态资源直出
location /static/ {
alias /var/www/static/;
}
# 动态请求统一交由 @app 处理
location / {
try_files $uri @app;
}
# 命名位置:内部跳转目标
location @app {
proxy_pass http://app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 错误页也复用同一逻辑(可选)
error_page 502 503 504 @app;}
这样,所有需要走后端的路径(包括 root、/api、/admin 等)都通过一次定义的 @app 执行,配置简洁、维护集中、无冗余。
注意作用域和变量继承
命名位置内可以使用外层 location 定义的变量(如 $args、$uri),但不能定义新 set 变量并期望在跳转前生效(因跳转是立即发生的)。如需动态构造目标地址:
- 用
rewrite ... break;先改写 URI,再proxy_pass(此时proxy_pass后不带 URI 路径,会拼接当前$uri) - 或用
map提前定义好目标 upstream,再在@name中引用 - 避免在
@name中写rewrite+last→ 会导致循环跳转(last重新匹配 location,可能又进同一个@name)










