一、Nginx rewrite模块的核心机制
Nginx的rewrite模块基于PCRE正则表达式实现URL路径和域名的灵活转换,其工作原理可分为三个关键阶段:
- 规则匹配阶段:通过
if或server块中的rewrite指令进行条件判断,支持~(区分大小写)、~*(不区分大小写)等正则修饰符。例如:if ($host != "example.com") {rewrite ^/(.*)$ https://example.com/$1 permanent;}
- 标志位控制:
last终止当前规则集处理并重启搜索,break直接停止处理,redirect(302)和permanent(301)控制重定向类型。测试时建议先用redirect验证逻辑。 - 变量应用:Nginx提供
$host、$http_x_forwarded_proto等200+内置变量,结合$1-$9捕获组可实现复杂跳转逻辑。如HTTPS强制跳转:server {listen 80;server_name example.com;rewrite ^ https://$host$request_uri? permanent;}
二、域名跳转的典型应用场景
1. 基础域名重定向
- 裸域名跳转:将
example.com跳转到www.example.comserver {server_name example.com;return 301 https://www.example.com$request_uri;}
- 多域名统一:将多个旧域名指向新主域
server {server_name old1.com old2.com;rewrite ^/(.*)$ https://new.com/$1 permanent;}
2. HTTPS强制跳转
结合$scheme变量实现协议升级:
server {listen 80;server_name example.com;return 301 https://$host$request_uri;}
对于反向代理场景,需额外处理X-Forwarded-Proto头:
map $http_x_forwarded_proto $proxy_scheme {default $scheme;https https;}server {if ($proxy_scheme != "https") {return 301 https://$host$request_uri;}}
3. 路径保留跳转
使用捕获组保持URL路径不变:
server {server_name old-site.com;rewrite ^/blog/(.*)$ https://new-site.com/articles/$1 permanent;}
三、性能优化与安全实践
1. 配置效率提升
- 优先使用
return:简单跳转时return 301比rewrite ... permanent性能高30% - 避免复杂正则:如
^/([a-z]+)/([a-z]+)/?$可拆分为多个简单规则 - 启用PCRE缓存:在nginx.conf中添加
pcre_jit on提升正则匹配速度
2. 安全防护措施
- 防止URL注入:对
$request_uri进行转义处理set $safe_uri $request_uri;if ($safe_uri ~* "(\.\.|/../)") {return 403;}
- 限制跳转频率:通过
limit_req模块防止滥用limit_req_zone $binary_remote_addr zone=rewrite_limit:10m rate=5r/s;server {location / {limit_req zone=rewrite_limit;# 正常跳转规则...}}
3. 监控与调试
- 日志记录:在
access_log中记录重定向信息log_format rewrite_log '$remote_addr - $host "$request" ''status $status redirect "$upstream_addr"';access_log /var/log/nginx/rewrite.log rewrite_log;
- 实时测试:使用
curl -I验证跳转状态码curl -I http://example.com# 应返回 HTTP/1.1 301 Moved Permanently
四、进阶配置技巧
1. 动态域名处理
结合Lua脚本实现动态跳转逻辑(需安装ngx_http_lua_module):
location / {set_by_lua $target 'local host = ngx.var.hostif host == "api.example.com" thenreturn "https://new-api.example.com"elsereturn "https://www.example.com"end';return 301 $target$request_uri;}
2. 条件跳转链
通过多个if实现复杂逻辑(注意Nginx的if是邪恶的,建议用map替代):
map $host$request_uri $redirect_url {default "";"~^old\.com/product/(.*)" "https://new.com/goods/$1";"~^beta\.old\.com" "https://preview.new.com";}server {if ($redirect_url) {return 301 $redirect_url;}}
3. 正则表达式优化
- 非捕获组:使用
(?:...)减少不必要的捕获rewrite ^/(?:en|fr)/news/(.*)$ https://global.example.com/news/$1 permanent;
- 预查断言:实现更精确的匹配
rewrite ^(?=.*\/api\/)(.*)$ https://api.example.com$1 permanent;
五、常见问题解决方案
-
跳转后丢失参数:确保使用
$request_uri而非$uri# 错误示例rewrite ^/old$ /new permanent; # 丢失查询参数# 正确写法rewrite ^/old$ /new$is_args$args permanent;
-
HTTPS跳转循环:检查是否同时存在80和443端口的跳转规则
-
正则匹配失效:确认正则修饰符是否正确,如
~*表示不区分大小写 -
性能瓶颈:对高流量站点,建议将重定向规则放在独立的
server块中
六、最佳实践建议
- 301与302的选择:永久变更用301(利于SEO),临时变更用302
- 测试环境验证:使用
nginx -t检查配置语法,通过strace跟踪执行过程 - 版本控制:对rewrite规则进行版本管理,便于回滚
- 缓存控制:对重定向响应设置
Cache-Control: no-store - 文档维护:为每条重定向规则添加注释说明其业务背景
通过系统掌握这些配置技巧,开发者可以构建出高效、安全、可维护的域名跳转系统。实际部署时建议先在测试环境验证所有跳转路径,确保不会出现意外重定向或信息泄露风险。