nginx中可用$arg_name变量配合if判断实现参数路由,需在location内使用=或~匹配参数值,通过set预设目标再proxy_pass,避免if内直接写proxy_pass或嵌套逻辑。

直接用 $arg_name 变量配合 if 判断就能实现,关键在于匹配方式选对、跳转动作写准,且注意 if 在 location 中的执行边界。
用 $arg_name 获取并判断参数值
Nginx 内置变量 $arg_name 会自动提取 URL 中 name=xxx 的值(不区分大小写,但参数名需完全一致)。例如请求 /api?name=admin,$arg_name 就是 "admin";若参数不存在,该变量为空字符串。
- 完全匹配写法:
if ($arg_name = "admin") { ... } - 正则匹配写法:
if ($arg_name ~ "^adm[ae]n$") { ... }(支持更灵活的校验) - 注意:
=是严格等于,==不合法;~区分大小写,~*不区分
跳转目标要明确指定 proxy_pass 或 return
if 块内不能直接写 location,只能做变量赋值或发起代理/响应。常见做法是:
- 用
set预设目标地址,再统一proxy_pass:set $upstream "http://backend-v2";if ($arg_env = "prod") { set $upstream "http://backend-prod"; }proxy_pass $upstream; - 用
return发起 HTTP 重定向(301/302):if ($arg_redirect = "true") { return 302 https://new.example.com$request_uri; } - 避免在
if中直接写proxy_pass http://...后跟其他指令,容易因执行顺序出错
必须放在 location 块内,且慎用嵌套逻辑
$arg_* 变量只在请求解析后可用,所以 if 必须写在 location 作用域里。另外 Nginx 的 if 是“伪指令”,有特殊执行规则:
- 它不会改变 URI 匹配流程,仅用于条件赋值或简单跳转
- 不支持
else,多条件要用多个if并注意顺序(先匹配的优先生效) - 不要在
if中尝试修改$request_uri或复杂重写,应改用rewrite指令
实际配置示例(带 fallback)
以下配置实现:当 name=user 时代理到新版服务,否则走默认服务:
location /api/ {
set $target "http://default-backend";
if ($arg_name = "user") {
set $target "http://user-backend";
}
if ($arg_name = "admin") {
set $target "http://admin-backend";
}
proxy_pass $target;
proxy_set_header Host $host;
}
这种写法清晰、可读性强,也便于后续扩展新分支。











