Nginx 的 if 指令仅限在 server 或 location 块中使用,不支持嵌套、逻辑运算符和 else 分支,仅允许单条件判断变量空值、字符串相等、正则匹配或文件存在性,且推荐优先用 map、try_files、limit_except 等更安全机制替代。

Nginx 的 if 指令可用于条件判断,但它不是万能的“编程语句”,用法受限且容易出错。它只在 server 和 location 块中可用,不能嵌套,也不能用于配置重写逻辑的首选方式(推荐优先用 rewrite 规则或 map 指令)。
if 的基本语法和可判断条件
if 后接一个表达式,表达式为真时执行其内部的单条指令(如 rewrite、return、set 等)。支持的判断类型有限:
- 检查变量是否为空(
"")或为 0:如$args、$http_user_agent - 匹配正则:用
~(区分大小写)、~*(不区分大小写) - 字符串相等:用
=或!= - 文件/目录存在性:用
-f(文件)、-d(目录)、-e(存在)、-x(可执行)
常见安全与性能陷阱
if 在 location 中使用时,会触发 Nginx 内部的“重试匹配”机制(即先按原 URI 匹配 location,再执行 if,若内部有 rewrite,则可能再次匹配 location),容易导致意料外的行为。例如:
下面这段看似简单,实际可能造成循环或跳过预期 location:
location / {
if ($args ~ "debug=1") {
rewrite ^(.*)$ /debug$1? break;
}
}更稳妥的做法是把这类逻辑前置到 server 块,或改用 map 预先计算结果。
替代 if 的更可靠方案
多数场景下,map 指令比 if 更清晰、更高效:
-
map在请求处理早期运行,无重试问题 - 支持多条件映射,可组合变量
- 可用于设置变量后,在
rewrite或return中引用
例如,根据参数启用调试模式:
map $args $debug_mode {
default "";
"~*debug=1" "on";
}
server {
location / {
if ($debug_mode = "on") {
rewrite ^(.*)$ /debug$1? break;
}
# 或直接用 try_files + 变量控制
}
}哪些情况可以谨慎用 if
仅限简单、无副作用的判断,且确保不会干扰 location 匹配流程:
- 拒绝特定 UA:
if ($http_user_agent ~* "sqlmap|nikto") { return 403; } - 强制 HTTPS 跳转(在 HTTP server 块中):
if ($scheme != "https") { return 301 https://$host$request_uri; } - 屏蔽空 Host 头:
if ($host = "") { return 444; }
注意:涉及 rewrite 的 if 尽量放在 server 级别,并配合 break 或 last 明确控制流向。


















