Nginx rewrite实现域名跳转:配置指南与实战解析

一、Nginx rewrite模块核心机制

Nginx的rewrite模块基于PCRE正则表达式实现URL重写,通过ngx_http_rewrite_module模块处理请求URI的转换。其核心工作原理包含三个关键步骤:

  1. 规则匹配:使用正则表达式匹配请求URI
  2. 变量替换:通过捕获组和变量构建新URI
  3. 重定向执行:根据标志位决定内部跳转或客户端重定向

在域名跳转场景中,rewrite模块可实现两种主要模式:

  • 永久重定向(301):适用于域名更换、HTTPS强制跳转
  • 临时重定向(302):适用于A/B测试、维护页面跳转

典型配置示例:

  1. server {
  2. listen 80;
  3. server_name old-domain.com;
  4. return 301 https://new-domain.com$request_uri;
  5. }

二、rewrite指令详解与参数配置

1. 基础语法结构

  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块名称

复杂场景示例:

  1. rewrite ^/old-path/(.*)$ /new-path/$1 permanent;

此配置将/old-path/xxx永久重定向到/new-path/xxx,保留路径参数。

三、典型域名跳转场景实现

1. HTTP到HTTPS强制跳转

  1. server {
  2. listen 80;
  3. server_name example.com;
  4. return 301 https://$host$request_uri;
  5. }

实现原理:捕获所有80端口请求,返回301状态码指向HTTPS对应路径

2. 域名合并与统一入口

  1. server {
  2. listen 80;
  3. server_name ~^(www\.)?(.+)$;
  4. if ($host ~* ^www\.(.*)$) {
  5. return 301 https://$2$request_uri;
  6. }
  7. location / {
  8. # 主站处理逻辑
  9. }
  10. }

此配置实现:

  • 自动去除www前缀
  • 统一跳转到非www域名
  • 保持路径和参数不变

3. 旧域名到新域名的平滑迁移

  1. server {
  2. listen 80;
  3. server_name old-domain.com;
  4. location / {
  5. rewrite ^/(.*)$ https://new-domain.com/$1 permanent;
  6. # 或使用return简化
  7. # return 301 https://new-domain.com$request_uri;
  8. }
  9. }

关键注意事项:

  • 使用permanent标志确保SEO权重传递
  • 测试阶段可先用redirect标志
  • 监控404错误日志及时调整规则

四、性能优化与调试技巧

1. 正则表达式优化原则

  1. 精确匹配优先:使用^$锚定字符串
  2. 避免过度捕获:仅捕获必要分组
  3. 预编译正则:高频访问规则可考虑预编译

性能对比示例:

  1. # 低效写法
  2. rewrite .*/user/(.*) /profile/$1;
  3. # 高效写法
  4. rewrite ^/user/([^/]+)/?$ /profile/$1 last;

2. 调试工具与方法

  1. 日志分析
    1. error_log /var/log/nginx/rewrite.log debug;
  2. 在线测试:使用regex101等工具验证正则表达式
  3. 实时监控:通过nginx -t测试配置语法

3. 常见问题解决方案

问题1:重定向循环

  • 原因:规则匹配导致无限跳转
  • 解决方案:添加条件判断
    1. if ($host != "new-domain.com") {
    2. rewrite ^(.*)$ https://new-domain.com$1 permanent;
    3. }

问题2:参数丢失

  • 原因:replacement字符串未包含$request_uri
  • 解决方案:显式指定参数
    1. rewrite ^/old$ /new?$args permanent;

五、安全加固建议

  1. 限制重定向目标

    1. map $host $redirect_target {
    2. default "";
    3. old-domain.com "https://new-domain.com";
    4. }
    5. server {
    6. if ($redirect_target) {
    7. return 301 $redirect_target$request_uri;
    8. }
    9. }
  2. 防止开放重定向漏洞

    • 严格校验目标域名
    • 避免直接使用用户输入构建URL
  3. HTTPS强制策略

    1. server {
    2. listen 443 ssl;
    3. server_name new-domain.com;
    4. # 强制HSTS
    5. add_header Strict-Transport-Security "max-age=31536000" always;
    6. }

六、进阶应用场景

1. 基于地理位置的域名跳转

  1. geo $country {
  2. default US;
  3. CN cn;
  4. JP jp;
  5. }
  6. map $country $domain {
  7. CN https://cn.example.com;
  8. JP https://jp.example.com;
  9. default https://us.example.com;
  10. }
  11. server {
  12. if ($domain) {
  13. return 301 $domain$request_uri;
  14. }
  15. }

2. 多级域名结构处理

  1. server {
  2. server_name ~^(?<subdomain>.+)\.example\.com$;
  3. location / {
  4. if ($subdomain = "api") {
  5. proxy_pass http://api_backend;
  6. }
  7. if ($subdomain = "blog") {
  8. rewrite ^/(.*)$ https://main-domain.com/blog/$1 permanent;
  9. }
  10. }
  11. }

3. 与Lua脚本集成

对于复杂逻辑,可结合OpenResty的Lua模块:

  1. location / {
  2. access_by_lua_block {
  3. local host = ngx.var.host
  4. if host == "old.com" then
  5. return ngx.redirect("https://new.com" .. ngx.var.request_uri, 301)
  6. end
  7. }
  8. proxy_pass http://backend;
  9. }

七、最佳实践总结

  1. 配置规范

    • 将重定向规则集中在独立server块
    • 使用注释说明规则用途
    • 定期清理无效规则
  2. 性能考量

    • 优先使用return而非rewrite+last
    • 避免在location块中使用复杂正则
  3. 维护建议

    • 建立重定向规则文档
    • 实施变更审批流程
    • 设置301/302重定向监控

典型生产环境配置示例:

  1. # HTTP到HTTPS重定向
  2. server {
  3. listen 80;
  4. server_name example.com www.example.com;
  5. return 301 https://example.com$request_uri;
  6. }
  7. # 主站配置
  8. server {
  9. listen 443 ssl;
  10. server_name example.com;
  11. ssl_certificate /path/to/cert.pem;
  12. ssl_certificate_key /path/to/key.pem;
  13. location / {
  14. # 主站处理逻辑
  15. }
  16. # 旧路径重定向
  17. location /old-section {
  18. return 301 /new-section;
  19. }
  20. }

通过系统掌握Nginx rewrite模块的配置方法,开发者能够高效实现各种域名跳转需求,在保证功能实现的同时兼顾性能与安全。实际部署时建议遵循”测试-监控-优化”的迭代流程,确保重定向规则的稳定运行。