1. Nginx Rewrite 基础概念解析
Rewrite 是 Nginx 服务器中一个极其重要的功能模块,它允许我们在不改变客户端请求的情况下,在服务器端修改请求的 URI。这个功能在以下场景中特别有用:
- URL 重定向(301/302)
- 动态 URL 伪装成静态 URL
- 域名切换时的流量迁移
- 多条件路由转发
rewrite 指令的基本语法格式为:
rewrite regex replacement [flag];其中:
- regex:用于匹配 URI 的正则表达式
- replacement:匹配成功后用于替换的字符串
- flag:标志位,用于控制重写行为
2. Rewrite 指令详解
2.1 正则表达式匹配规则
Nginx 使用的正则表达式与 Perl 兼容(PCRE),以下是一些常用匹配模式:
^:匹配字符串开头 $:匹配字符串结尾 .:匹配任意单个字符 *:匹配前一个字符0次或多次 +:匹配前一个字符1次或多次 ?:匹配前一个字符0次或1次 \d:匹配数字 \w:匹配字母、数字或下划线 {n}:精确匹配n次 {n,}:匹配至少n次 {n,m}:匹配n到m次2.2 常用 Flag 标志位
Nginx rewrite 支持以下几种 flag:
- last:停止处理当前 rewrite 指令集,并用修改后的 URI 重新匹配 location
- break:停止处理当前 rewrite 指令集
- redirect:返回302临时重定向
- permanent:返回301永久重定向
重要提示:last 和 break 的区别在于是否会重新发起 location 匹配,这在复杂配置中需要特别注意。
3. 实战应用场景
3.1 基础重定向示例
将旧URL重定向到新URL:
rewrite ^/old-page.html$ /new-page.html permanent;动态URL伪静态化:
rewrite ^/product/(\d+).html$ /product.php?id=$1 last;3.2 多条件重写规则
复杂业务场景下的多条件判断:
location / { if ($http_user_agent ~* "mobile") { rewrite ^(.*)$ /mobile/$1 break; } if ($request_method = POST) { rewrite ^/api/(.*)$ /backend/$1 last; } }3.3 域名重定向配置
全站HTTPS重定向:
server { listen 80; server_name example.com; return 301 https://$host$request_uri; }多域名统一规范:
server { listen 80; server_name www.example.com; rewrite ^(.*)$ https://example.com$1 permanent; }4. 高级技巧与性能优化
4.1 重写规则优化建议
- 将最常匹配的规则放在前面
- 避免过于复杂的正则表达式
- 尽量使用 break 而非 last 减少匹配次数
- 对静态资源使用 break 直接终止匹配
4.2 常见问题排查
- 重写循环问题:
rewrite ^/(.*)$ /$1 last; # 错误的循环示例- 变量使用不当:
rewrite ^/path$ /new-path?param=$arg_param; # 保留原始参数- 特殊字符转义:
rewrite "^/search/([^/]+)/?$" /search.php?q=$1 last;5. 实际案例解析
5.1 电商网站URL优化
商品详情页重写:
rewrite ^/product-([0-9]+)-([a-z]+)\.html$ /product.php?id=$1&name=$2 last;分类页分页处理:
rewrite ^/category/([^/]+)/page/([0-9]+)$ /category.php?name=$1&page=$2 last;5.2 API版本控制
RESTful API版本管理:
location /api { rewrite ^/api/v1/(.*)$ /api_v1/$1 last; rewrite ^/api/v2/(.*)$ /api_v2/$1 last; }5.3 多语言站点路由
语言前缀处理:
rewrite ^/(en|fr|de)/(.*)$ /$2?lang=$1 last;6. 性能监控与调试
6.1 日志记录配置
调试rewrite规则时,可以开启rewrite日志:
server { rewrite_log on; error_log /var/log/nginx/rewrite.log notice; }6.2 变量查看技巧
在配置中输出调试信息:
location /debug { add_header X-Debug-URI $uri; add_header X-Debug-Args $args; return 200 'Debug Info'; }7. 安全注意事项
- 避免开放重定向漏洞:
# 不安全的写法 rewrite ^/redirect/(.*)$ $1 permanent; # 安全的写法 rewrite ^/redirect/(https?://example\.com/.*)$ $1 permanent;- 限制重写范围:
location /safe-area { rewrite ^/safe-area/(.*)$ /$1 last; }- 敏感路径保护:
location ~* \.(php|asp|jsp)$ { deny all; }8. 最佳实践总结
经过多年Nginx配置经验,我总结了以下rewrite最佳实践:
- 保持规则简洁明了,适当添加注释
- 复杂规则先在小范围测试
- 使用return替代rewrite进行简单重定向
- 定期审查rewrite规则,移除不再使用的部分
- 重要变更先在测试环境验证
对于高频访问的路径,建议使用map指令进行优化:
map $uri $new_uri { include /etc/nginx/rewrite-maps/*.conf; } server { rewrite ^ $new_uri last; }最后分享一个实用技巧:在修改rewrite规则后,可以使用nginx -t测试配置语法,然后通过nginx -s reload平滑重启,这样可以避免服务中断。