0%

Nginx重定向

Nginx 重定向配置详解:return 与 rewrite 的实战指南

重定向是 Web 服务中常见的功能,用于将客户端请求从一个 URL 转发到另一个 URL(如域名迁移、路径调整、HTTPS 强制跳转等)。Nginx 通过returnrewrite两种方式实现重定向,各有适用场景。本文详细讲解两种方式的语法、区别及实战案例,帮助灵活配置重定向规则。

重定向基础:状态码与场景

重定向通过 HTTP 状态码告知客户端跳转类型,常用状态码:

  • 301 Moved Permanently:永久重定向(客户端会缓存跳转关系,适合域名更换);
  • 302 Found:临时重定向(客户端不缓存,适合临时维护、活动页面跳转);
  • 307 Temporary Redirect:临时重定向(严格保留请求方法,如 POST 请求不会转为 GET);
  • 308 Permanent Redirect:永久重定向(严格保留请求方法)。

return指令:简单直接的重定向

return指令用于直接返回状态码和跳转 URL,语法简洁,适合固定规则的重定向(如域名跳转、HTTPS 强制跳转)。

1. 语法格式

1
2
3
4
5
6
7
8
# 格式1:仅返回状态码(如404)
return code;

# 格式2:返回状态码+跳转URL
return code url;

# 格式3:直接返回URL(默认302状态码)
return url;

2. 实战示例

  • HTTP 强制跳转 HTTPS

    1
    2
    3
    4
    5
    6
    server {
    listen 80;
    server_name example.com www.example.com;
    # 所有HTTP请求永久重定向到HTTPS
    return 301 https://$host$request_uri;
    }
    • 说明:$host自动获取请求的域名,$request_uri保留完整路径和参数(如/api?page=1)。
  • 域名迁移(旧域名跳新域名)

    1
    2
    3
    4
    5
    6
    server {
    listen 80;
    server_name old.example.com;
    # 旧域名永久跳转到新域名,保留路径
    return 301 https://new.example.com$request_uri;
    }
  • 路径重定向(单页跳转)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    server {
    listen 80;
    server_name example.com;

    location /old-page {
    # 临时跳转到新页面
    return 302 /new-page;
    }
    }

3. return的优势

  • 执行效率高:一旦匹配return,立即终止后续处理,适合作为优先规则;
  • 语法简单:无需正则表达式,适合固定 URL 跳转;
  • 支持变量:可通过 Nginx 变量(如$host$request_uri)动态生成跳转 URL。

rewrite指令:基于正则的灵活重定向

rewrite指令通过正则表达式匹配 URL,并替换为新的 URL,适合复杂规则的重定向(如路径替换、动态参数调整)。

1. 语法格式

1
rewrite regex replacement [flag];
  • regex:用于匹配 URL 的正则表达式(如^/old/(.*)$);
  • replacement:替换后的 URL(如/new/$1$1表示正则中的第一个分组);
  • flag:跳转类型(控制重定向后的处理逻辑,可选值见下文)。

2. 常用flag说明

flag 作用 适用场景
last 完成当前 rewrite 后,用新 URL 重新匹配所有 location 规则 内部路径重写(如/article/123/article.php?id=123
break 完成当前 rewrite 后,停止后续匹配,继续执行当前 location 内的其他指令 代理场景(如配合proxy_pass
redirect 返回 302 临时重定向,URL 以http:///https://开头时生效 临时外部跳转
permanent 返回 301 永久重定向,URL 以http:///https://开头时生效 永久外部跳转

last和break两者很像,但是使用alias指令时必须使用last,使用proxy_pass时必须使用break,last在本条rewrite执行之后,会对其所在的server{}重新发起请求,而break在本条rewrite执行之后,则会终止匹配

3. 实战示例

  • 路径替换(带参数)

    1
    2
    3
    4
    # 将 /article/123 重写为 /article.php?id=123(内部跳转,地址栏不变)
    location / {
    rewrite ^/article/(\d+)$ /article.php?id=$1 last;
    }
    • 说明:(\d+)匹配数字(如 123),$1引用该分组,last表示用新 URL 重新匹配 location。
  • 文件后缀替换

    1
    2
    3
    4
    # 将 .html 后缀的URL重定向为 .php(外部跳转,地址栏变化)
    location / {
    rewrite ^/(.*)\.html$ /$1.php permanent;
    }
    • 效果:访问/page.html会永久跳转到/page.php
  • 配合代理的重写

    1
    2
    3
    4
    5
    # 访问 /api/xxx 时,重写为后端的 /v2/xxx 并代理(内部处理,地址栏不变)
    location /api/ {
    rewrite ^/api/(.*)$ /v2/$1 break; # 使用break避免循环
    proxy_pass http://backend;
    }
    • 注意:代理场景必须用break,否则last会导致 Nginx 重新匹配 location,可能引发死循环。

4. 正则表达式常用语法

rewrite依赖正则匹配,掌握基础语法是关键:

符号 含义 示例
^ 匹配字符串开头 ^/api 匹配以/api开头的 URL
$$` 匹配字符串结尾 \.html$$ 匹配以.html`结尾的 URL
. 匹配任意单个字符 a.b 匹配aabacb
* 匹配前面字符 0 次或多次 ab* 匹配aababb
+ 匹配前面字符 1 次或多次 ab+ 匹配ababb等(不匹配a
? 匹配前面字符 0 次或 1 次 ab? 匹配aab
() 分组(可通过$1$2引用) (a)(b)$1=a$2=b
[] 匹配字符集中的任意一个 [0-9] 匹配任意数字

returnrewrite的区别与选择

维度 return rewrite
语法复杂度 简单(无需正则) 复杂(依赖正则)
执行效率 高(立即终止处理) 较低(需正则匹配)
适用场景 固定 URL 跳转(如 HTTPS、域名迁移) 动态 URL 重写(如路径替换、参数调整)
灵活性 低(仅支持变量拼接) 高(支持正则分组、条件匹配)

选择建议

  • 简单跳转(如 HTTPS 强制跳转、域名迁移)优先用return
  • 复杂规则(如路径正则替换、参数提取)用rewrite
  • 性能敏感场景(如高并发 API)尽量用return,减少正则开销。

高级技巧与注意事项

  1. 重定向日志调试
    开启rewrite_log可记录重写过程,便于排查规则问题:

    1
    2
    3
    4
    http {
    rewrite_log on; # 开启重写日志(默认记录到error_log,级别notice)
    error_log /var/log/nginx/rewrite.log notice; # 单独存储重写日志
    }
  2. 避免循环跳转
    确保重写后的 URL 不会再次被同一规则匹配,例如:

    1
    2
    3
    4
    5
    # 错误示例:/new 会被重写为 /new/,然后再次匹配规则,导致循环
    rewrite ^/(.*)$ /$1/ permanent;

    # 正确示例:排除已带斜杠的URL
    rewrite ^/(.*[^/])$ /$1/ permanent;
  1. 结合if条件判断
    对特定条件应用重定向(如特定 User-Agent):

    1
    2
    3
    4
    5
    6
    location / {
    # 移动端用户跳转到移动端页面
    if ($http_user_agent ~* "Mobile") {
    rewrite ^/$ /mobile permanent;
    }
    }

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10