一、rewrite 和 return 的核心区别是什么¶
原笔记在同一章里先讲了 return,再讲 rewrite,其实已经暗示了两者的分工:
return更适合简单直接地返回状态码或固定新地址rewrite更适合基于 URI 做匹配和改写
也就是说,rewrite 的重点不是“立刻返回”,而是:
- 先匹配 URI
- 再根据正则结果重写 URL
这也是它更灵活、同时也更容易写复杂的原因。
二、rewrite 主要匹配什么内容¶
原笔记特别提醒了一点:
rewrite匹配的是 URI- 不是完整的 URL
这意味着在写规则时,关注的是:
- 域名后面的路径部分
而不是整条完整网址。
这和前面 location 匹配 URI 的思路是相通的。
三、rewrite 指令的基本格式¶
原笔记把格式概括为:
rewrite 找什么 替换成什么 [标记];
可以进一步理解成:
- 左边:匹配规则,支持具体内容、正则、捕获分组
- 右边:替换后的内容,可以用后向引用
- 最后:可选标记,决定改写后的处理方式
原笔记还提到,这个思路和 sed 's###g' 非常像,本质上都是“匹配再替换”。
四、案例:把整个站点跳转到另一个域名¶
原笔记的示例配置如下:
server {
listen 80;
server_name rewrite.oldboylinux.cn;
rewrite ^(.*)$ http://www.baidu.com$1;
}
这条规则的含义是:
- 把用户请求的 URI 全部捕获到
$1 - 再拼接到新域名后面
例如访问:
/aaa
就会跳成:
http://www.baidu.com/aaa
这类写法很适合:
- 旧域名整体迁移到新域名
- 原路径还需要尽量保留下来
五、为什么默认会得到 302¶
原笔记在第一次测试时发现:
- 没写额外标记时
- 返回的是
302 Found
这是因为 rewrite 默认使用的是:
redirect
也就是临时跳转。
原笔记的测试结果正好验证了这一点:
- 访问旧地址
- 返回
302
这说明没有显式指定时,Nginx 会把它当成临时改写跳转处理。
六、如何改成 301 永久跳转¶
原笔记随后把配置改成:
server {
listen 80;
server_name rewrite.oldboylinux.cn;
rewrite ^(.*)$ http://www.baidu.com$1 permanent;
}
此时再次测试,就会返回:
301 Moved Permanently
这也是原笔记想强调的核心区别:
redirect对应302permanent对应301
在真实业务里,一般可以这样理解:
- 新旧地址都还可能同时使用,用
302 - 旧地址要彻底废弃、权重和收录转移到新地址,用
301
七、break 和 last 又是什么¶
原笔记最后补充了另外两个非常常见的标记:
7.1 break¶
原笔记的解释是:
- 一旦匹配到包含
break的规则 - 即使后面还有其他
location规则 - 也不再继续执行后续改写逻辑
可以把它理解为:
- 当前这次改写在这里停止
- 不再继续往后跑
7.2 last¶
原笔记对 last 的描述更偏向“重新开始一轮匹配”:
- 命中带
last的rewrite后 - 当前改写阶段停止
- Nginx 会重新发起一次内部请求
- 再次和
location规则进行匹配
因此,last 更像是:
- 改写完成后,再拿新 URI 去重新走一轮匹配流程
这也是它和 break 最大的区别。
八、原笔记总结的常见标记含义¶
可以把原笔记中的几个标记整理成下面这张表:
| 标记 | 含义 |
|---|---|
redirect |
302,临时跳转 |
permanent |
301,永久跳转 |
break |
终止继续执行后续改写流程 |
last |
重新发起内部请求,再走一轮匹配 |
这几个标记决定的不是“匹配不匹配”,而是“匹配成功后接下来怎么处理”。
九、小结¶
rewrite 的核心价值在于:
它可以让你基于 URI 和正则表达式,对访问路径做更灵活的改写。
原笔记这一节最值得先记住的几件事是:
rewrite匹配的是 URI- 默认标记是
redirect,也就是302 permanent用于301break和last决定改写后是否继续执行或重新匹配
当简单跳转用 return 不够时,rewrite 往往就是更合适的下一步。