nginx rewrite不生效主因是匹配顺序与执行阶段错误:先选location再执行其内rewrite,若请求未进入目标location则规则无效;需确认location优先级、正则匹配条件、flag行为及uri编码格式。

排查 Nginx rewrite 规则不生效,核心是理解 匹配顺序 和 执行阶段。规则写了却没反应,往往不是语法错,而是被前面的 location 或 rewrite 拦截、覆盖或跳过了。
location 匹配优先级决定 rewrite 是否有机会执行
Nginx 先选 location,再在该 location 内执行 rewrite。如果请求根本没进到写 rewrite 的那个 location 块,规则自然不生效。
- 检查
location类型:精确匹配(=)、前缀匹配(^~)、正则匹配(~或~*)优先级不同。正则匹配虽灵活,但优先级低于^~和= - 用
nginx -T(全量 dump 配置)确认实际生效的是哪个 location。注意 include 的文件是否被正确加载 - 临时加
return 200 "in this location";到目标 location 里,curl 验证是否真进来了
rewrite 指令位置和 flag 影响后续流程
rewrite 不是“写完就改”,它的执行时机和 flag 直接决定是否继续匹配、是否跳转、是否终止当前 location。
-
last:停止当前 location 内的 rewrite,重新匹配 location(可能进另一个块,原 rewrite 就“失效”了) -
break:停止当前 location 内所有 rewrite,不重新匹配,继续执行本 location 后续指令(如 proxy_pass) -
redirect/permanent:302/301 跳转,不走后续配置,客户端重发请求 - 漏写 flag 是常见坑——默认是
last,容易引发循环或误跳
正则表达式本身没匹配上
看似写了规则,但 URI 根本不满足 pattern,rewrite 就像没写一样。
- URI 是 未经解码 的原始路径(如
%20不会自动变成空格),正则要按编码后字符串写 - location 中的正则匹配的是 去除 host 和 query string 后的路径部分,且开头不带
/(除非你显式加了) - 用
log_format记录$request_uri、$uri、$args,对比真实输入和预期 pattern
其他易忽略点
一些配置细节会让 rewrite “静默失败”。
-
rewrite_log on;+error_log /path/to/log notice;可以看到每条 rewrite 是否触发、是否匹配、怎么跳转(需编译时带 debug 日志支持) - server 块顶层写的 rewrite,在进入 location 前就执行,但只对 root 请求有效;多数场景应写在 location 内
- 多个 rewrite 按书写顺序逐条执行,前一条用
last就终止后续,用break就停在本 location - proxy_pass 与 rewrite 共存时,注意
$uri是否被改写影响后端路径(比如末尾斜杠丢失)











