0

Nginx rewrite flag参数详解:last、break、redirect、permanent到底怎么选

2026.05.26 | youres | 15次围观

做 Nginx 配置的时候,rewrite 指令大家肯定不陌生,但后面的 flag 参数——lastbreakredirectpermanent——很多人搞不清楚什么时候该用哪个。用错了轻则不生效,重则导致死循环返回 500 错误。今天把这四个 flag 一次性讲透。

先弄懂 rewrite 指令的基础语法

Nginx 官方文档对 rewrite 的定义是:用正则表达式匹配请求 URI,匹配上了就按 replacement 字符串改写 URI。语法是这样的:

rewrite regex replacement [flag];

举个例子,把下载路径中的 /media/ 替换成 /mp3/

rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;

这里的关键就是最后那个 flag——它决定了改写完之后 Nginx 接下来干什么。

四个 flag 一一拆解

1. last——重新搜索 location

last flag 时,Nginx 会停止执行当前 server 块内剩余的 rewrite 指令,然后以新的 URI 重新搜索一遍 location 匹配规则,再在新匹配到的 location 里继续处理。

典型场景:需要多级内部跳转,比如在一个 server 块里做多次规则匹配。

server {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
    return 403;  # 只有上面两条都不匹配才走到这里
}

2. break——停在当前 context

breaklast 名字差不多,但行为完全不同。break 同样是停止执行当前 rewrite 指令集,但不会重新搜索 location,直接在这个 location 里继续处理后续请求。

简单说:last 跳转,break 不跳转。

location /download/ {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
    return 403;
}

注意:如果在 /download/ 这个 location 里用了 last 而不是 break,Nginx 会重新搜索 location,导致最多 10 次循环后返回 500 错误。官方文档专门指出了这个坑。

3. redirect——返回 302 临时重定向

redirect 会告诉浏览器:「这个页面临时搬走了,请去新地址看看」,返回 302 状态码。浏览器收到 302 后会自己跳转到新地址,下次访问还是先请求旧地址。

rewrite ^/old-page(.*)$ /new-page$1 redirect;

如果 replacement 字符串以 http://https://$scheme 开头,即使不写 redirect flag,Nginx 也会默认返回 302 重定向。

4. permanent——返回 301 永久重定向

permanent 返回 301 状态码,告诉浏览器和搜索引擎:「这个页面永久迁移了,请记住新地址」,浏览器会缓存这个跳转。

rewrite ^/old-page(.*)$ https://example.com/new-page$1 permanent;

做 HTTPS 迁移或者域名更换时,通常会用 permanent 而不是 redirect,因为 301 能传递搜索引擎权重。

一张表总结四个 flag 的区别

Flag是否重搜索 location返回给浏览器是否缓存典型场景
last✅ 重新搜索无(内部跳转)多级 rewrite 链
break❌ 不重搜索无(内部跳转)单个 location 内的 URI 改写
redirect302 临时重定向❌ 不缓存临时迁移、灰度发布
permanent301 永久重定向✅ 浏览器缓存域名更换、HTTPS 迁移

实战中容易踩的几个坑

坑一:location 里用了 last 导致循环

这是最常见的错误。在 location 块内使用 last 会触发重新搜索 location,如果正则没写好,很容易形成「rewrite → 匹配同一 location → 再 rewrite」的死循环,Nginx 默认限制最多 10 次,超过就返回 500。

解决方法:location 块内用 break,server 块顶层的 rewrite 才用 last

坑二:redirect 和 permanent 用错场景

如果不确定是否要永久迁移,先用 redirect(302)。一旦设了 permanent(301),浏览器会长期缓存,搜索引擎也会更新索引,后面想改回来就麻烦了。

坑三:rewrite 后面参数被重复追加

如果 replacement 字符串里带了新参数,旧参数会自动追加在后面:

# 请求: /show?user=john
# rewrite 后: /show?user=jane&user=john  ← 参数重复了!
rewrite ^/users/(.*)$ /show?user=$1 last;

解决方法:在 replacement 末尾加个 ? 阻止追加旧参数:

rewrite ^/users/(.*)$ /show?user=$1? last;

坑四:正则里的大括号和分号要加引号

如果正则表达式包含 }; 字符,整个正则必须用引号包起来:

rewrite "^(.*)\.(js|css)$" /static/$1.$2 break;

常见配置实例

例1:把旧域名请求重定向到新域名(301 永久)

server {
    listen 80;
    server_name old-example.com;
    rewrite ^/(.*)$ https://new-example.com/$1 permanent;
}

例2:临时维护页面(302)

rewrite ^/.*$ /maintenance.html redirect;

例3:去掉 URL 中的尾巴(比如 .html 后缀标准化)

location / {
    rewrite ^(.+)\.html$ $1 break;
    try_files $uri $uri/ /index.html;
}

例4:基于正则的多条件 rewrite(last)

server {
    rewrite ^/article/(\d+)$ /post?id=$1 last;
    rewrite ^/page/(\d+)$ /index?p=$1 last;
    # 都匹配不上就走默认处理
}

总结

Nginx rewrite 的四个 flag 看似简单,实际上涉及到 location 匹配规则、请求处理流程等多个知识点。记住两个核心区别

  • last vs break:前者会重新搜索 location,后者不会;前者用于 server 顶层,后者用于 location 内部。
  • redirect vs permanent:前者 302 浏览器不缓存,后者 301 浏览器会缓存,SEO 效果不同。

配置之前先想清楚需求:是浏览器要跳转(redirect/permanent),还是 Nginx 内部改写 URI(last/break)?方向对了,配置才不会白写。


相关推荐:

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论
882文章数 0评论数
作者其它文章