Nginx可通过map指令实现基于域名的动态路径跳转,即在http块中定义$host到$backend_prefix等变量的映射,再于proxy_pass或return中引用,支持精确/正则匹配及default默认值。

在 Nginx 中,基于域名的虚拟主机本身不直接支持“动态路径跳转”,但可以通过 map 指令结合 server_name 和请求路径,实现按域名映射不同后端路径或重定向逻辑——这是一种轻量、高效且配置灵活的动态路由方式。
理解 map 指令的核心作用
map 是 Nginx 的变量映射模块(需启用 ngx_http_map_module,默认已编译),它能在请求处理早期根据某个源变量(如 $host、$request_uri)生成一个新变量。这个新变量后续可在 location、proxy_pass、return 等指令中使用,从而实现条件化行为。
关键点:
- 必须定义在
http块中,不能放在server或location内 - 匹配是精确的(支持正则和通配符,但需加波浪线
~或星号*) - 未匹配时变量值为空字符串,建议用
default设默认值
按域名映射不同代理路径(推荐场景)
例如:同一台 Nginx 同时托管 app1.example.com 和 app2.example.com,希望将所有请求分别转发到 http://backend-app1/ 和 http://backend-app2/api/(注意后者带固定前缀)。
配置示例:
http {
# 定义域名 → 后端路径前缀的映射
map $host $backend_prefix {
default "";
app1.example.com "/";
app2.example.com "/api/";
}
<pre class="brush:php;toolbar:false;">server {
listen 80;
server_name app1.example.com app2.example.com;
location / {
proxy_pass http://127.0.0.1:8000$backend_prefix;
proxy_set_header Host $host;
}
}
}
说明:
- 当访问
app2.example.com/v1/users时,$backend_prefix为/api/,最终代理到http://127.0.0.1:8000/api/v1/users - 路径拼接由 Nginx 自动完成,
proxy_pass末尾有斜杠才触发路径替换逻辑
按域名+路径组合做条件重定向
若需对特定域名下的某些路径做跳转(如把旧版路径统一重写),可用 map 组合 $host 和 $request_uri:
http {
map "$host:$request_uri" $redirect_target {
default "";
"legacy.example.com/old" https://new.example.com/migrated;
"legacy.example.com/old/v2" https://new.example.com/v2;
}
<pre class="brush:php;toolbar:false;">server {
listen 80;
server_name legacy.example.com;
location / {
if ($redirect_target) {
return 301 $redirect_target;
}
# 其他正常处理...
}
}
}
注意:
- 这里用双引号包裹
"$host:$request_uri"是为了构造复合键,避免因冒号出现在 host 或 uri 中导致误匹配 -
if在location中仅用于简单判断(如变量非空),不推荐复杂逻辑
常见陷阱与优化建议
实际使用中容易忽略的关键细节:
-
map不支持嵌套或运行时计算,所有映射必须静态定义 - 域名匹配区分大小写,
example.com和EXAMPLE.COM视为不同键 - 若需通配匹配(如
*.example.com),应使用正则:~^.*\.example\.com$,并确保map块启用正则支持 - 大量域名映射时,考虑用
include分离配置文件,提升可维护性
这种方式比用多个 server 块重复写 location 更简洁,也比在每个 location 中用 if 判断更高效。











