map指令必须在http块中定义,用于根据源变量值动态生成目标变量,支持精确匹配、通配符和正则匹配,按序执行且需default兜底,变量惰性求值、只读不可修改。

map 指令用于在 Nginx 全局(即 http 块)中定义变量映射关系,它不是直接处理请求的指令,而是动态生成变量值的机制。它的核心作用是:根据某个源变量(如 $host、$arg_lang)的值,查表得出目标变量的值,供后续 location、if、proxy_pass 等指令使用。
map 必须放在 http 块内,不能在 server 或 location 中
这是硬性要求。Nginx 启动时会预编译所有 map 规则,因此只允许出现在 http{...} 顶层作用域中。
示例:
http {
# ✅ 正确:在 http 块中定义
map $host $backend {
default "default_backend";
example.com "app_v1";
api.example.com "api_v2";
~^staging\.(.*) "staging_$1";
}
<pre class="brush:php;toolbar:false;">server {
listen 80;
location / {
proxy_pass http://$backend; # 使用 map 生成的变量
}
}}
支持精确匹配、通配符和正则匹配
map 的匹配规则按顺序从上到下执行,遇到第一个匹配项即停止(类似 switch-case)。支持三类模式:
-
字符串精确匹配:如
example.com→ 匹配完整 host 字符串 -
前缀通配符 *:如
*.example.com→ 匹配以该后缀结尾的 host(注意:必须写成*.example.com,不能写*.example.*) -
正则匹配(以 ~ 开头):如
~^v(\d+)\.api\.example\.com$→ 可捕获分组,用于构造新值(如"api_v$1")
⚠️ 注意:default 必须存在(或至少有一个无条件匹配),否则未匹配时变量为空字符串,可能引发意外行为。
map 变量是惰性求值且只读的
map 定义的变量(如 $backend)不会在配置加载时计算,而是在每次请求中、首次被引用时才执行匹配逻辑。它不可被 set、rewrite 或其他指令修改,仅作“查表取值”用。
常见误用规避:
- ❌ 不要在 map 中引用尚未定义的变量(如
map $undefined_var $x { ... }) - ❌ 不要用 map 替代 rewrite:map 不改变 URI、不跳转、不终止流程,只赋值
- ✅ 推荐组合:map + proxy_pass / return / add_header,实现基于 host、参数、UA 的动态路由或响应头注入
调试 map 是否生效的小技巧
可通过 add_header 把 map 变量输出到响应头,方便 curl 验证:
location /debug {
add_header X-Backend "$backend";
return 200 "backend: $backend";
}
然后执行:curl -H 'Host: api.example.com' http://localhost/debug,观察响应头或正文是否符合预期。











