Nginx中用rewrite配合if实现条件重定向,核心是先判断条件(如$scheme、$host、$args等),再执行rewrite或return跳转;if仅支持单条指令、不支持else和逻辑运算符,推荐优先使用return替代rewrite以避免循环风险。

用 rewrite 配合 if 实现条件重定向,核心是先判断条件是否成立,再执行重定向动作。Nginx 的 if 不支持 else,但足够应对多数跳转场景,比如 HTTP 强制跳 HTTPS、非 www 域名跳转 www、特定 User-Agent 重定向等。
基本写法:if + rewrite 组合
if 必须写在 server 或 location 块内,里面只能放单条指令(如 rewrite、return、set)。常见写法如下:
if ($scheme = http) { rewrite ^/(.*)$ https://$host/$1 permanent; }if ($host != "www.example.com") { rewrite ^/(.*)$ https://www.example.com/$1 permanent; }if ($args ~ "utm_source=oldsite") { return 301 https://example.com$uri; }
注意:rewrite 后的 permanent 表示 301 永久跳转,redirect 表示 302 临时跳转;路径匹配只作用于 URI(即域名后部分),不包含查询参数($args)。
更安全推荐:用 return 替代 rewrite 做跳转
当只是做简单跳转(尤其是带协议+域名的完整 URL),return 比 rewrite 更直接、不易出错,且不触发重写循环:
if ($scheme = http) { return 301 https://$host$request_uri; }if ($host ~ "^example\.com$") { return 301 https://www.example.com$request_uri; }if ($http_user_agent ~* "curl|wget") { return 403; }
$request_uri 包含原始 URI 和全部参数,比手动拼 更可靠;return 立即响应,不进入后续 rewrite 流程,避免隐式循环风险。
关键注意事项
Nginx 的 if 是“伪指令”,在 location 中使用时行为较特殊,容易引发意料外的结果:
-
if内部不能嵌套,也不支持逻辑运算符&&或||;多个条件需拆成多个if或改用map指令 - 变量为空或为
"0"时,if判为 false;以"0"开头的字符串(如"0123")在旧版 Nginx(1.0.1 之前)也会判为 false - 慎用
rewrite ... last在if中——它会重启 location 匹配,可能造成循环;优先用break或return - 所有正则匹配(
~、~*、!~等)区分大小写与否、是否取反,要严格对照语义选对符号
实用例子:强制 www + HTTPS
一个常见需求是统一访问入口,可在一个 server 块中同时处理 HTTP 和 HTTPS 请求:
server {
listen 80;
listen 443 ssl;
server_name example.com www.example.com;
<pre class="brush:php;toolbar:false;">ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# HTTP 请求全部跳 HTTPS
if ($scheme = http) {
return 301 https://www.example.com$request_uri;
}
# 非 www 域名跳转到 www
if ($host = "example.com") {
return 301 https://www.example.com$request_uri;
}
root /var/www/html;
index index.html;}
这个配置确保所有流量最终都落在 https://www.example.com,且不会因重复匹配导致 500 错误。











