Plainnotes

用 map 把 if 从 nginx 配置里赶出去

2024-12-22 · 3 分钟部署

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,其余尽量换掉。