map指令只能在http或server块中定义,用于启动时建立请求特征到变量的静态映射,不可在location内使用,但可在location中引用其变量实现动态路由。

Nginx 中的 map 指令本身不能直接写在 location 块内,它只能出现在 http 或 server 上下文中。但你可以用 map 提前定义变量,再在 location 中通过 if、set 或匹配逻辑引用这些变量,从而实现“动态配置”的效果。
map 指令的作用是变量映射,不是运行时判断
map 是在 Nginx 启动或重载配置时一次性计算并建立键值映射关系的指令,它不支持运行时条件分支,也不支持嵌套或复杂表达式。它的核心价值在于把请求特征(如 Host、URI、Header)映射为一个可复用的变量,供后续指令使用。
- 映射源可以是任意内置变量(
$host、$args、$http_user_agent等) - 目标变量必须以
$开头,且不能与已有变量同名 - 支持正则匹配、默认值(
default)、空值处理("")
在 location 中使用 map 变量的典型方式
定义好 map 后,在 location 块中可通过 if 判断变量值、用 set 衍生新值,或配合 proxy_pass、return、rewrite 实现动态行为。
- 用
if ($my_backend) { ... }控制代理目标或返回码 - 用
set $upstream_host $my_backend;再传给proxy_pass http://$upstream_host; - 配合
try_files或error_page实现基于变量的路径路由
一个实用示例:按域名动态选择后端集群
比如根据 Host 头自动切换 upstream:
http {
map $host $backend {
default "default-backend";
~^app\.example\.com$ "app-cluster";
~^api\.example\.com$ "api-cluster";
~^admin\.example\.com$ "admin-cluster";
}
upstream default-backend { server 10.0.1.10:8080; }
upstream app-cluster { server 10.0.2.20:8080; }
upstream api-cluster { server 10.0.3.30:8080; }
upstream admin-cluster { server 10.0.4.40:8080; }
server {
listen 80;
location / {
proxy_pass http://$backend;
proxy_set_header Host $host;
}
}
}
注意:proxy_pass 后必须带协议和变量(如 http://$backend),不能只写 $backend;Nginx 会自动解析变量对应的 upstream 名称。
注意事项与常见陷阱
map 的变量在 location 中可用,但某些上下文(如 log_format、access_log)也支持;而 if 在 location 中虽可用,但不推荐用于复杂逻辑——应优先用 map + proxy_pass 这类无副作用的方式。
-
map不支持在location内定义,否则会报错 “map directive is not allowed here” -
map中的正则匹配以~开头,大小写敏感;~*表示忽略大小写 - 变量值为空字符串时,
if判断会视为 false,但proxy_pass会报错,需确保default覆盖所有情况 - 避免在
map中调用耗时函数(Nginx 不支持),所有映射必须是静态或正则规则


















