一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Nginx Rewrite 规则中条件判断如何配

时间:2026-08-18 20:15:49 编辑:袖梨 来源:一聚教程网

Nginx rewrite不支持直接写多条件逻辑,需用if配合map预计算变量实现安全判断;if仅支持单条件且不可嵌套,复杂逻辑应通过map生成布尔变量再用if触发rewrite。

Nginx 的 rewrite 规则本身不支持直接写复杂的条件判断(比如 if ($arg_x = "y") && ($http_user_agent ~* chrome) 这类组合逻辑),它依赖 if 指令配合 rewrite 使用,但要注意:iflocation 块中行为受限,且嵌套、多条件组合容易出错。真正可靠的条件判断需结合 mapifrewrite 分层设计。


用 if 指令做基础条件判断

if 是 Nginx 中唯一能写条件表达式的地方,语法简单但限制多:

  1. 只能出现在 serverlocation 块内
  2. 不支持 && / || 运算符(不能写 if (A && B)
  3. 条件成立时才执行其内部的 rewritesetreturn 等指令

正确写法(单条件):

location /old/ {if ($arg_type = "pdf") {rewrite ^/old/(.*)$ /new/pdf/$1 permanent;}if ($http_referer ~* .baidu.com) {rewrite ^/download/(.*)$ /cdn/$1 redirect;}}

❌ 错误写法(多条件连写):

# Nginx 会直接报错:invalid conditionif ($arg_id != "" && $arg_type = "img") { ... }

多个条件组合:用 map 预计算变量

map 指令在 http 块中定义,可基于多个变量生成新变量,适合“与/或”逻辑:

http {map "$arg_id:$arg_type" $should_rewrite {default0;"~^[0-9]+:img$"1; # id 是数字 且 type=img"~^:pdf$" 1; # id 为空(空字符串)且 type=pdf}server {location /files/ {if ($should_rewrite) {rewrite ^/files/(.*)$ /static/$1 break;}}}}

这样就把“$arg_id 非空 AND $arg_type == img”这种逻辑,转成一个预判变量 $should_rewrite,再用 if 判断,安全又清晰。


常见条件变量参考

这些变量可直接在 ifmap 中使用:

  1. $args:完整查询参数字符串(如 a=1&b=2
  2. $arg_xxx:单个参数值(如 $arg_id?id=123 的值)
  3. $http_xxx:请求头(如 $http_user_agent, $http_referer
  4. $host, $request_uri, $scheme, $https
  5. $request_methodGETPOST
  6. 正则匹配操作符:=, !=, ~(区分大小写)、~*(忽略大小写)、!~ / !~*

⚠️ 注意:$args 修改后(如 rewrite ...?a=1 last)不会自动更新 $arg_a,要用 $query_string 或重写后重新解析。


替代方案:优先用 try_files + named location

对复杂跳转逻辑,比 if + rewrite 更可靠:

location / {# 先检查是否有特定参数,有则进命名 locationif ($arg_v = "2") {rewrite ^(.*)$ @v2 last;}try_files $uri $uri/ =404;}location @v2 {rewrite ^/api/(.*)$ /v2/api/$1 break;proxy_pass http://backend;}

或者更推荐完全避开 if,用 map + error_page + named location 实现条件分流,尤其在高并发场景下更稳定。


Nginx 的条件重写不是写代码,关键在“拆解逻辑 + 预判变量 + 少用 if”。把判断提前到 map,把动作收束到 location,能避开大部分坑。

热门栏目