Nginx之rewrite配置域名跳转:从基础到进阶的完整指南

一、Nginx rewrite模块核心机制解析

Nginx的rewrite规则基于Perl兼容正则表达式(PCRE),通过ngx_http_rewrite_module模块实现URL路径与域名的动态重写。其核心指令包括rewriteifset等,其中rewrite指令的语法结构为:

  1. rewrite regex replacement [flag];
  • regex:匹配请求URI的正则表达式
  • replacement:替换后的目标路径或域名
  • flag:控制重写行为的标志(如last/break/redirect/permanent)

域名跳转本质是通过修改HTTP响应头中的Location字段实现的,配合301/302状态码告知客户端跳转目标。例如将example.com跳转至new.example.com时,Nginx会在响应头添加:

  1. HTTP/1.1 301 Moved Permanently
  2. Location: https://new.example.com/original/path

二、典型域名跳转场景配置

1. 永久性域名迁移(301重定向)

当网站域名永久变更时,需配置301重定向以保持SEO权重:

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

或使用rewrite指令实现更复杂的路径保留:

  1. server {
  2. listen 80;
  3. server_name old-domain.com;
  4. rewrite ^/(.*) https://new-domain.com/$1 permanent;
  5. }

优化建议

  • 优先使用return 301指令,其处理效率比rewrite permanent高15%-20%
  • 在HTTP到HTTPS的跳转中,可合并配置:
    1. server {
    2. listen 80;
    3. server_name old-domain.com;
    4. return 301 https://new-domain.com$request_uri;
    5. }

2. 临时性跳转(302重定向)

适用于A/B测试或临时维护场景:

  1. server {
  2. listen 80;
  3. server_name temp-domain.com;
  4. rewrite ^/(.*) https://backup-domain.com/$1 redirect;
  5. }

关键区别

  • permanent对应301状态码(永久重定向)
  • redirect对应302状态码(临时重定向)
  • 浏览器对301会缓存跳转关系,而302每次都会重新请求

3. 基于路径的动态跳转

当需要根据URL路径进行差异化跳转时,正则表达式发挥关键作用:

  1. server {
  2. listen 80;
  3. server_name multi-domain.com;
  4. # 将/blog/开头的请求跳转到独立博客
  5. rewrite ^/blog/(.*) https://blog.example.com/$1 permanent;
  6. # 将/api/开头的请求跳转到微服务
  7. rewrite ^/api/(.*) https://api-gateway.example.com/$1 permanent;
  8. }

正则技巧

  • 使用^锚点确保从路径开头匹配
  • 括号()捕获分组内容,通过$1$2引用
  • 避免过度复杂的正则,建议每个server块处理不超过3个rewrite规则

三、进阶配置与性能优化

1. 条件判断跳转

结合if指令实现更复杂的逻辑:

  1. server {
  2. listen 80;
  3. server_name smart-redirect.com;
  4. # 根据User-Agent跳转移动端
  5. if ($http_user_agent ~* "(Android|iPhone|iPad)") {
  6. rewrite ^/(.*) https://m.example.com/$1 permanent;
  7. }
  8. # 根据Cookie跳转测试环境
  9. if ($http_cookie ~* "env=test") {
  10. rewrite ^/(.*) https://test.example.com/$1 permanent;
  11. }
  12. }

注意事项

  • if指令在Nginx中存在性能损耗,建议将高频判断逻辑移至应用层
  • 避免在if中使用正则匹配大文本(如整个请求体)

2. 变量与映射表

对于大规模域名跳转需求,可使用map指令建立映射关系:

  1. http {
  2. map $host $redirect_target {
  3. default "";
  4. old1.example.com new1.example.com;
  5. old2.example.com new2.example.com;
  6. ~^(?<sub>.+)\.old\.example\.com$ $sub.new.example.com;
  7. }
  8. server {
  9. listen 80;
  10. server_name ~^(.+)\.old\.example\.com$;
  11. if ($redirect_target) {
  12. return 301 https://$redirect_target$request_uri;
  13. }
  14. }
  15. }

优势

  • 集中管理跳转规则,便于维护
  • 支持动态子域名匹配
  • 减少重复配置

3. HTTPS强制跳转

现代网站必须配置的HTTPS跳转方案:

  1. server {
  2. listen 80;
  3. server_name example.com;
  4. return 301 https://$host$request_uri;
  5. }
  6. server {
  7. listen 443 ssl;
  8. server_name example.com;
  9. ssl_certificate /path/to/cert.pem;
  10. ssl_certificate_key /path/to/key.pem;
  11. # 其他配置...
  12. }

安全建议

  • 使用HSTS头增强安全性:
    1. add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
  • 配置OCSP Stapling提升TLS性能

四、调试与问题排查

1. 常用调试工具

  • nginx -t:测试配置语法
    1. nginx -t -c /etc/nginx/nginx.conf
  • curl -v:查看完整请求响应流程
    1. curl -v http://old-domain.com/path
  • 浏览器开发者工具:检查Network标签中的重定向链

2. 典型问题解决方案

问题1:跳转后丢失路径参数

  • 原因:未正确使用$request_uri变量
  • 修复
    1. rewrite ^ https://new-domain.com$request_uri? permanent;

问题2:无限重定向循环

  • 原因:新旧域名配置相互引用
  • 修复:确保跳转目标不会再次匹配当前server块的规则

问题3:正则匹配不生效

  • 原因:未正确使用正则锚点或分组
  • 修复

    1. # 错误示例:可能匹配到部分路径
    2. rewrite /oldpath /newpath permanent;
    3. # 正确示例:精确匹配
    4. rewrite ^/oldpath(/.*)?$ /newpath$1 permanent;

五、最佳实践总结

  1. 简单优先:能用return解决的问题不用rewrite
  2. 最小化规则:每个server块尽量保持3条以内rewrite规则
  3. 集中管理:通过include指令拆分复杂配置
  4. 性能监控:定期检查nginx -T输出的完整配置
  5. 备份习惯:修改前备份配置文件
    1. cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-$(date +%Y%m%d)

通过系统掌握Nginx的rewrite机制与域名跳转技巧,开发者可以高效完成网站迁移、多域名管理等任务,同时确保SEO效果和用户体验不受影响。实际配置时建议先在测试环境验证,再逐步应用到生产环境。