last 重写后从 server 开始重新匹配 location,break 则留在原 location 继续执行;redirect 返回 302 临时跳转,permanent 返回 301 永久跳转并影响缓存与 seo;无 flag 时 rewrite 会循环执行直至超限。

last 和 break:重写后是否重新匹配 location
两者都会终止当前 rewrite 指令块中后续规则的执行,但关键区别在于重写后的 URI 是否参与新一轮 location 匹配。
-
last:重写完成后,Nginx 会丢弃当前 location 上下文,用新 URI 从 server 块开始重新走一遍 location 匹配流程。适合需要跳转到另一个 location 处理逻辑的场景,比如将
/api/v1/xxx重写为/v1/xxx后交由location /v1/处理。 - break:重写完成后,仍在原 location 内继续执行——不再查找其他 location,而是直接尝试访问 root 或 alias 指向的文件,或执行该 location 内剩余指令(如 return、proxy_pass)。若重写后路径在当前 location 下无对应资源,容易返回 404。
redirect 和 permanent:客户端重定向行为差异
二者都让浏览器跳转,地址栏 URL 会变化,但 HTTP 状态码和缓存策略完全不同。
- redirect:发出 302 响应,表示临时重定向。浏览器每次请求原地址都会发起跳转,不缓存重定向结果,搜索引擎也不传递权重。适用于灰度发布、A/B 测试等短期调整。
- permanent:发出 301 响应,表示永久重定向。浏览器会缓存该跳转关系,后续请求直接发往新地址;搜索引擎将原 URL 的权重转移至新 URL。网站迁移、域名更换等长期变更应使用它。
使用位置影响 last/break 行为
rewrite 指令若写在 location 块外(如 server 级),last 和 break 效果一致,都只终止本组 rewrite 执行,不涉及 location 跳出问题。
但一旦写在 location 块内,行为立刻分化:
- location 内的 last 会“跳出”当前 location,触发完整匹配流程;
- location 内的 break 则“留在原地”,后续仅按当前 location 配置处理(比如读取静态文件、执行 return)。
没有 flag 时的默认行为
若 rewrite 指令末尾未写任何 flag,Nginx 会把重写后的 URI 当作新输入,**循环执行本组所有 rewrite 规则**(包括已执行过的),直到某次重写不再匹配,或达到最大迭代次数(默认 10 次)而报 500 错误。
这种行为易引发意外循环,例如:
rewrite ^/(.*)$ /index.php?path=$1;若没加 flag,可能反复重写导致崩溃。生产环境强烈建议显式指定 flag,避免隐式循环。











