nginx 的 set 指令仅支持字符串变量定义且限于 rewrite 阶段,不能实现编程式条件逻辑;主要配合 if、rewrite 等做简单字符串操作,推荐用 map 替代 set+if 实现安全清晰的映射。

Nginx 本身不支持传统编程语言中的“变量赋值 + 条件分支”逻辑,set 指令只能定义字符串类型的局部变量,且仅在 rewrite 阶段生效,不能直接用于 if 外的条件判断或复杂逻辑控制。它的主要用途是配合 if、rewrite、return 等指令做简单字符串操作和跳转,而非实现类似编程语言的 if-else 或 switch。
set 指令的基本用法和限制
set 必须写在 server 或 location 块内,语法为 set $var_name value;。注意:
- 变量名必须以
$开头,且只能包含字母、数字、下划线 - 右侧值可以是字符串、Nginx 内置变量(如
$arg_xxx、$host)、或它们的拼接(支持简单字符串连接,但不支持运算) -
set在 rewrite 阶段执行,且每个请求中按配置顺序依次执行;重复赋值会覆盖前值 -
set不能在if块外直接触发逻辑分支,也不能用于保存布尔结果供后续多处判断
用 set + if 实现简单逻辑分流
常见做法是先用 set 提取或构造一个标识值,再用 if 判断该变量做跳转或改写。例如根据请求参数设置标记并重定向:
location /api/ {
set $route "";
if ($arg_v = "2") {
set $route "v2";
}
if ($arg_v = "3") {
set $route "v3";
}
if ($route = "v2") {
rewrite ^/api/(.*)$ /v2/$1 break;
}
if ($route = "v3") {
rewrite ^/api/(.*)$ /v3/$1 break;
}
}
注意:if 在 location 中慎用(尤其避免嵌套或与 rewrite 混用),Nginx 官方建议优先用 map 指令替代。
更推荐:用 map 替代 set + if 做逻辑映射
map 是 Nginx 内置的高效变量映射机制,声明在 http 块中,支持多条件匹配、默认值、正则和嵌套,比 set+if 更安全、可读性更强:
http {
map $arg_v $api_version {
"" "v1";
"2" "v2";
"3" "v3";
default "v1";
}
server {
location /api/ {
rewrite ^/api/(.*)$ /$api_version/$1 break;
}
}
}
这样既避免了 if 的潜在陷阱(如内部重定向行为异常),又实现了清晰的逻辑映射。
set 的典型实用场景
尽管不能做复杂逻辑,set 在以下轻量场景仍很实用:
- 拼接路径或 Host:如
set $backend_host "backend-$env.example.com"; - 标准化参数值:如
set $uid $arg_user_id;后统一用于日志或限流 - 配合
rewrite构造目标 URI:如set $new_path "/static/$arg_file"; rewrite ^(.*)$ $new_path last; - 临时标记用于
if判断(仅限单层、无副作用的简单分支)
不复杂但容易忽略:set 定义的变量生命周期仅限当前请求的 rewrite 阶段,无法跨阶段(如 log 阶段)直接使用,如需记录,应搭配 log_format 引用该变量。











