last是rewrite标志,作用为终止当前location内rewrite执行,并用新uri从server块重新开始location匹配;break则终止rewrite后仍在原location内继续处理,不重启匹配。

在 Nginx 中,last 并不是“终止当前重写并重新搜索新的 Location”,而是让 Nginx **停止当前 location 块内的 rewrite 指令执行,并用新 URI 重新发起内部请求匹配(即重新进行 location 查找)**。它不跳出 server 块,也不触发外部重定向,是纯内部跳转。
什么是 last?
last 是 rewrite 指令的标志之一,作用是:完成当前 rewrite 后,Nginx 会用生成的新 URI,从头开始匹配 location(即再次执行 location 查找),然后进入匹配到的 location 块继续处理(包括其中的 rewrite、proxy_pass 等)。它和 break 的关键区别在于是否重启 location 匹配。
last 的典型使用场景
常见于需要将请求“转发”到另一个路径规则、且该路径有独立配置(如静态资源处理、反向代理等)时:
- 把 /api/v1/xxx 映射到 /v1/xxx,再由 /v1/ 开头的 location 处理
- 统一入口(如 /app/*)重写为后端服务路径,交由专门的 proxy location 处理
- 实现路径前缀标准化,避免重复写 proxy_pass 或 root
怎么正确使用 last?
注意以下几点才能让它按预期工作:
- 必须配合可匹配的新 URI:rewrite 后的 URI 应能被某个 location 块精确或前缀匹配到,否则可能陷入 404 或循环
- 不能出现在 if 块中(除非在较新版本且谨慎使用):if 块内 rewrite + last 容易引发不可预期行为,Nginx 官方不推荐
-
location 必须存在且生效:例如 rewrite 成
/backend/$1,就得有location /backend/ { ... } - 避免无限循环:确保 rewrite 后的 URI 不会再次命中同一个 rewrite 规则(可通过 location 前缀隔离,或加条件判断)
一个可运行的例子
假设想把所有 /old-api/xxx 请求内部重写为 /new-api/xxx,并交由 location /new-api/ 处理:
location /old-api/ {
rewrite ^/old-api/(.*)$ /new-api/$1 last;
}
location /new-api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
}
当请求 /old-api/users 时:
→ 进入 /old-api/ location
→ rewrite 成 /new-api/users,执行 last
→ Nginx 放弃当前 location,用 /new-api/users 重新匹配 location
→ 匹配到 /new-api/,执行 proxy_pass
不复杂但容易忽略。











