用 map 把 if 从 nginx 配置里赶出去
nginx 的 if 在 location 里有很多反直觉行为,官方文档专门有一节叫 “If is Evil”。多数场景可以用 map 替代:
map $http_user_agent $is_bot {
default 0;
~*(bot|crawler|spider) 1;
}
map $request_uri $redirect_to {
~^/old/(.*)$ /new/$1;
default "";
}
map 在 http 块里定义,结果是变量,可以在 location、proxy_set_header、return 里用,没有 if 的作用域陷阱。
常见替代:
- 按 UA 分流 →
map出变量,proxy_pass到不同 upstream。 - 旧路径重定向 →
map+return 301 $redirect_to。 - 按 Host 选证书 →
map $ssl_server_name $cert。
只有极少数场景(比如 if ($request_method = POST) 配合 limit_except)还得用 if,其余尽量换掉。