nginx rewrite模块默认已内置,关键在于正确作用域(server/location/if)中编写指令、选用合适flag(如last、permanent)、配合set/return等指令并调试验证。

Nginx 的 rewrite 模块(ngx_http_rewrite_module)默认已编译进大多数官方发行版,无需额外加载;配置重写规则的关键不是“启用模块”,而是**在正确的作用域中写对指令、用对标志、理清执行顺序**。
rewrite 规则写在哪?作用域决定行为
rewrite 指令可出现在 server、location 和 if 块中,但执行优先级和后续处理逻辑差异很大:
-
server 块中的 rewrite:最早执行,在 location 匹配前就改写 URI。若用
last,会触发重新匹配整个 server 下的 location;若用break,则在当前 server 内继续处理,不再进入任何 location。 - location 块内的 rewrite:仅对该 location 匹配到的请求生效。推荐把业务相关重写放在这里,更安全可控。
-
if 块中的 rewrite:慎用。if 在 location 中本身就有陷阱(比如不支持嵌套、部分变量不可用),且 if + rewrite 组合容易引发意外循环或跳过关键逻辑。优先考虑用
return或try_files替代。
核心指令怎么配合使用?
rewrite 不是单打独斗的指令,它常与 set、if、return 协同完成复杂逻辑:
- 用
set $var value;提前定义变量,比如提取域名、判断环境,再在 rewrite 中引用(如rewrite ^(.*)$ /$1?env=$var permanent;)。 - 用
if ($host ~* "^www\.(.*)$") { set $domain $1; }配合后续 rewrite 实现子域归一化。 - 用
return 301 https://$host$request_uri;强制 HTTPS,比 rewrite 更直接高效,也避免正则开销。 - 避免在 if 中写多个 rewrite;更稳妥的做法是:条件判断 → 设置变量 → 外层用 rewrite 引用变量。
标志位(flag)选哪个?直接影响流程
flag 控制 rewrite 后的走向,选错会导致 404、循环重定向或规则失效:
-
permanent:返回 301,浏览器地址栏会变,适合域名迁移、SEO 固化。 -
redirect:返回 302,临时跳转,适合灰度、维护页。 -
last:内部重写后,用新 URI 重新匹配 location —— 这是实现伪静态、API 版本路由的核心机制。 -
break:重写后停止当前块内所有 rewrite,也不再匹配新 location,适合简单路径替换后直接交给后端。
调试与验证不能少
rewrite 规则看不见摸不着,出问题很难排查:
- 开启
rewrite_log on;(需同时设置日志级别为 notice),错误日志里会输出每次匹配和替换过程。 - 用
curl -I http://example.com/old看响应头里的Location和状态码,确认是否 301/302 或内部重写成功。 - 注意正则细节:URI 不含参数和协议,
$request_uri才带 query string;匹配时记得转义点号(\.)、锚定开头结尾(^和$)防止误匹配。











