1. Nginx rewrite功能核心解析
rewrite是Nginx服务器最常用的核心模块之一,它允许我们在不改变客户端原始请求的情况下,修改请求的URI。这个功能在以下场景中特别有用:
- 网站改版后保持旧URL可访问
- 实现伪静态化(如将动态参数转化为目录形式)
- 统一规范化URL格式
- 实现AB测试分流
- 处理多域名统一跳转
rewrite模块通过PCRE正则表达式进行模式匹配,语法格式为:
nginx复制rewrite regex replacement [flag];
重要提示:rewrite规则会按照配置顺序依次执行,直到匹配到第一条规则为止(除非使用特定flag改变此行为)。我建议将最具体的规则放在前面,通用规则放在后面。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. rewrite指令深度配置指南
2.1 基础匹配模式
最简单的rewrite示例:
nginx复制rewrite ^/oldpage$ /newpage permanent;
这个规则会将/oldpage永久重定向(301)到/newpage。其中:
^/oldpage$是精确匹配模式permanent是flag标志
2.2 正则表达式进阶
Nginx使用PCRE正则引擎,支持捕获组:
nginx复制rewrite ^/product/([0-9]+)/?$ /item.php?id=$1 last;
这个规则将/product/123/转换为/item.php?id=123。注意:
([0-9]+)捕获数字序列/?使末尾斜杠可选$1引用第一个捕获组
2.3 常用flag解析
| Flag | 作用 | 典型场景 |
|---|---|---|
| last | 停止处理当前rewrite规则集 | 重写后需要进一步处理 |
| break | 立即停止所有rewrite处理 | 最终重定向目标 |
| redirect | 302临时重定向 | A/B测试分流 |
| permanent | 301永久重定向 | 网站永久迁移 |
3. 实战配置案例精讲
3.1 全站HTTPS强制跳转
nginx复制server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
这个配置会:
- 监听80端口HTTP请求
- 301跳转到相同URL的HTTPS版本
- 保留原始请求的host和URI
3.2 多域名统一规范化
nginx复制server {
listen 80;
server_name www.example.com example.com;
if ($host != 'www.example.com') {
rewrite ^/(.*)$ http://www.example.com/$1 permanent;
}
}
这个配置确保:
- 无论访问example.com还是www.example.com
- 最终都统一跳转到www子域名
- 保持原始请求路径不变
3.3 动态URL伪静态化
nginx复制rewrite ^/blog/([0-9]{4})/([0-9]{2})/([0-9]{2})/(.+)$ /blog.php?year=$1&month=$2&day=$3&title=$4 last;
这个高级规则:
- 将/blog/2023/05/20/some-title格式URL
- 转换为/blog.php带参数的形式
- 同时保持URL美观和SEO友好
4. 性能优化与调试技巧
4.1 rewrite性能影响
rewrite规则会带来额外CPU开销,特别是在高并发场景下。优化建议:
- 减少正则复杂度,避免回溯
- 将高频访问的规则放在前面
- 对静态资源避免使用rewrite
- 合理使用break标志终止处理
4.2 调试方法
在nginx.conf中添加调试日志:
nginx复制error_log /var/log/nginx/rewrite.log notice;
rewrite_log on;
日志会显示:
- 每个请求经历的rewrite过程
- 匹配的规则和替换结果
- 最终处理的URI
4.3 常见问题排查
-
循环重定向问题:
- 检查rewrite条件是否自包含
- 使用curl -v跟踪重定向链
- 考虑改用return指令
-
规则不生效:
- 检查nginx -t配置测试
- 确认server_name匹配
- 检查location嵌套层级
-
特殊字符处理:
- URL编码问题使用$request_uri
- 中文路径需要特别处理
- 问号参数使用$is_args$args
5. 高级应用场景
5.1 条件rewrite
结合map指令实现智能重定向:
nginx复制map $http_user_agent $redirect_rule {
default 0;
"~*bot" 1;
}
server {
if ($redirect_rule) {
rewrite ^ /bot-page.html break;
}
}
这个配置会对爬虫访问特殊处理。
5.2 灰度发布分流
nginx复制set $group A;
if ($http_cookie ~* "group=B") {
set $group B;
}
location / {
rewrite ^/(.*)$ /$group/$1 last;
}
实现基于cookie的AB测试分流。
5.3 动态反向代理
nginx复制rewrite ^/service/([^/]+)(/.*)$ $2 break;
proxy_pass http://$1;
这个模式可以实现:
- 将/service/backend1/xxx代理到backend1服务器
- 动态解析服务名称
- 保持路径结构不变
6. 安全防护实践
6.1 注入防护
对用户输入内容严格过滤:
nginx复制if ($request_uri ~* "[<>]") {
return 403;
}
阻止包含HTML标签的恶意请求。
6.2 敏感目录隐藏
nginx复制location ~* /(\.git|config|backup) {
return 404;
}
防止源代码和配置文件泄露。
6.3 防盗链配置
nginx复制valid_referers none blocked server_names ~\.google\.;
if ($invalid_referer) {
rewrite ^/images/.+\.(jpg|png)$ /403.png break;
}
只允许特定来源访问图片资源。
在实际生产环境中,我建议将rewrite规则按功能分类存放于不同include文件中,例如:
code复制conf.d/
├── rewrite/
│ ├── basic.conf
│ ├── security.conf
│ └── seo.conf
这样既方便管理,也利于团队协作维护。每次修改后记得用nginx -t测试配置,然后graceful reload生效。
