一、Nginx rewrite模块核心机制
Nginx的rewrite模块基于PCRE正则表达式实现URL重写,通过ngx_http_rewrite_module模块处理请求URI的转换。其核心工作原理包含三个关键步骤:
- 规则匹配:使用正则表达式匹配请求URI
- 变量替换:通过捕获组和变量构建新URI
- 重定向执行:根据标志位决定内部跳转或客户端重定向
在域名跳转场景中,rewrite模块可实现两种主要模式:
- 永久重定向(301):适用于域名更换、HTTPS强制跳转
- 临时重定向(302):适用于A/B测试、维护页面跳转
典型配置示例:
server {listen 80;server_name old-domain.com;return 301 https://new-domain.com$request_uri;}
二、rewrite指令详解与参数配置
1. 基础语法结构
rewrite regex replacement [flag];
regex:PCRE兼容的正则表达式replacement:替换字符串,支持$1-$9捕获组flag:控制重定向行为的标志位
2. 关键标志位解析
| 标志位 | 作用 | 典型场景 |
|---|---|---|
| last | 终止当前server块处理,重新搜索location | 多级重定向 |
| break | 终止rewrite处理,继续执行当前location | 内部重写 |
| redirect | 返回302临时重定向 | 测试环境 |
| permanent | 返回301永久重定向 | 生产环境 |
3. 变量系统应用
Nginx提供丰富的内置变量:
$host:请求主机头$request_uri:完整原始URI(含参数)$scheme:协议类型(http/https)$server_name:当前server块名称
复杂场景示例:
rewrite ^/old-path/(.*)$ /new-path/$1 permanent;
此配置将/old-path/xxx永久重定向到/new-path/xxx,保留路径参数。
三、典型域名跳转场景实现
1. HTTP到HTTPS强制跳转
server {listen 80;server_name example.com;return 301 https://$host$request_uri;}
实现原理:捕获所有80端口请求,返回301状态码指向HTTPS对应路径
2. 域名合并与统一入口
server {listen 80;server_name ~^(www\.)?(.+)$;if ($host ~* ^www\.(.*)$) {return 301 https://$2$request_uri;}location / {# 主站处理逻辑}}
此配置实现:
- 自动去除www前缀
- 统一跳转到非www域名
- 保持路径和参数不变
3. 旧域名到新域名的平滑迁移
server {listen 80;server_name old-domain.com;location / {rewrite ^/(.*)$ https://new-domain.com/$1 permanent;# 或使用return简化# return 301 https://new-domain.com$request_uri;}}
关键注意事项:
- 使用
permanent标志确保SEO权重传递 - 测试阶段可先用
redirect标志 - 监控404错误日志及时调整规则
四、性能优化与调试技巧
1. 正则表达式优化原则
- 精确匹配优先:使用
^和$锚定字符串 - 避免过度捕获:仅捕获必要分组
- 预编译正则:高频访问规则可考虑预编译
性能对比示例:
# 低效写法rewrite .*/user/(.*) /profile/$1;# 高效写法rewrite ^/user/([^/]+)/?$ /profile/$1 last;
2. 调试工具与方法
- 日志分析:
error_log /var/log/nginx/rewrite.log debug;
- 在线测试:使用regex101等工具验证正则表达式
- 实时监控:通过
nginx -t测试配置语法
3. 常见问题解决方案
问题1:重定向循环
- 原因:规则匹配导致无限跳转
- 解决方案:添加条件判断
if ($host != "new-domain.com") {rewrite ^(.*)$ https://new-domain.com$1 permanent;}
问题2:参数丢失
- 原因:replacement字符串未包含
$request_uri - 解决方案:显式指定参数
rewrite ^/old$ /new?$args permanent;
五、安全加固建议
-
限制重定向目标:
map $host $redirect_target {default "";old-domain.com "https://new-domain.com";}server {if ($redirect_target) {return 301 $redirect_target$request_uri;}}
-
防止开放重定向漏洞:
- 严格校验目标域名
- 避免直接使用用户输入构建URL
-
HTTPS强制策略:
server {listen 443 ssl;server_name new-domain.com;# 强制HSTSadd_header Strict-Transport-Security "max-age=31536000" always;}
六、进阶应用场景
1. 基于地理位置的域名跳转
geo $country {default US;CN cn;JP jp;}map $country $domain {CN https://cn.example.com;JP https://jp.example.com;default https://us.example.com;}server {if ($domain) {return 301 $domain$request_uri;}}
2. 多级域名结构处理
server {server_name ~^(?<subdomain>.+)\.example\.com$;location / {if ($subdomain = "api") {proxy_pass http://api_backend;}if ($subdomain = "blog") {rewrite ^/(.*)$ https://main-domain.com/blog/$1 permanent;}}}
3. 与Lua脚本集成
对于复杂逻辑,可结合OpenResty的Lua模块:
location / {access_by_lua_block {local host = ngx.var.hostif host == "old.com" thenreturn ngx.redirect("https://new.com" .. ngx.var.request_uri, 301)end}proxy_pass http://backend;}
七、最佳实践总结
-
配置规范:
- 将重定向规则集中在独立server块
- 使用注释说明规则用途
- 定期清理无效规则
-
性能考量:
- 优先使用
return而非rewrite+last - 避免在location块中使用复杂正则
- 优先使用
-
维护建议:
- 建立重定向规则文档
- 实施变更审批流程
- 设置301/302重定向监控
典型生产环境配置示例:
# HTTP到HTTPS重定向server {listen 80;server_name example.com www.example.com;return 301 https://example.com$request_uri;}# 主站配置server {listen 443 ssl;server_name example.com;ssl_certificate /path/to/cert.pem;ssl_certificate_key /path/to/key.pem;location / {# 主站处理逻辑}# 旧路径重定向location /old-section {return 301 /new-section;}}
通过系统掌握Nginx rewrite模块的配置方法,开发者能够高效实现各种域名跳转需求,在保证功能实现的同时兼顾性能与安全。实际部署时建议遵循”测试-监控-优化”的迭代流程,确保重定向规则的稳定运行。