map指令必须定义在http块顶层,不能出现在server或location中;它通过源变量查表生成目标变量,运行时o(1)查表,支持正则匹配与default默认值,proxy_pass引用时须为upstream名且不可带斜杠。

直接用 map 指令,别写 if 块做条件转发 —— 后者在 location 里行为不可靠,容易漏匹配、触发重复重写,且不支持变量嵌套,性能也差。
map 必须定义在 http 块里,不能放 server 或 location 中
map 是 Nginx 的全局映射机制,只在配置加载时解析一次,运行时查表 O(1)。如果误写进 server 或 location,Nginx 启动会直接报错:nginx: [emerg] "map" directive is not allowed here。
-
map只能出现在http{...}块顶层,和upstream、include同级 - 变量名必须以
$开头,且目标变量(如$backend_upstream)不能提前被其他指令定义过 - 请求头字段自动转为小写+下划线格式:比如
X-Service→$http_x_service,X-Api-Version→$http_x_api_version - 若 header 不存在或为空,该变量值为空字符串,会走
default分支(没写 default 就是空值,后续proxy_pass会 502)
proxy_pass 引用变量时,地址必须带协议且不能含 URI 路径
这是最常踩的坑:proxy_pass http://$backend_upstream ✅,但 proxy_pass http://$backend_upstream/ ❌ —— 末尾斜杠会让 Nginx 丢弃原始请求路径,强制重写为根路径。
- 正确写法:
proxy_pass http://$backend_upstream;(无斜杠),原始 URI 完整透传 - 错误写法:
proxy_pass http://$backend_upstream/;(带斜杠),/test/api 变成 /api,但前提是 $backend_upstream 是域名/IP;若它本身是http://10.0.1.10:8080这种,加斜杠反而导致路径截断 - 如果真要改写路径(比如去掉前缀),必须用
rewrite+break配合,且不能和proxy_pass变量混用在同一个if块里
Header 值含下划线时需开启 underscores_in_headers on
默认情况下,Nginx 会忽略所有带下划线的请求头(如 X_User_Id),因为 RFC 规定 header 名应只含字母、数字、连字符。如果你的客户端确实发了 X_User_Id: 123,但 $http_x_user_id 始终为空,就是这个原因。
- 在
http或server块里加一行:underscores_in_headers on; - 该指令不影响已有的连字符命名(如
X-Api-Key),只放开下划线支持 - 开启后,仍需按规则转小写+下划线引用:
X_User_Id→$http_x_user_id,不是$http_x_user_id
真正难处理的不是语法,而是 header 值的边界情况:空格、大小写混用、编码字符、多值逗号分隔——map 只做字符串精确匹配或正则,不自动 trim 或 normalize。上线前务必用 curl -H 'X-Service: user-api ' 这类带空格的请求实测 fallback 是否生效。











