Nginx 中 Rewrite 规则如何在 server 块和 location 块中正确配置生效

作者:袖梨 2026-08-22

rewrite规则必须放在server或location块内才能生效,写在http顶层会报错;server块中rewrite先执行并影响location匹配,location块中rewrite仅在匹配后触发,flag决定重定向或内部重写。

rewrite 规则必须放在 serverlocation 块内才能生效,写在 http 块顶层会直接报错:“directive is not allowed here”。关键不在“写了没”,而在“写在哪”和“怎么执行”。

server 块里的 rewrite:先执行、影响后续 location 匹配

server 块中的 rewrite 在任何 location 匹配前就运行,它修改的是原始请求 URI,从而改变 location 的匹配结果。

  1. 适合做全局路径标准化,比如统一去除末尾斜杠:rewrite ^/(.*)/$ /$1 permanent;
  2. 慎用 break 或无 flag 的重写——它可能让本该进 location /api/ 的请求,因 URI 被提前改写而错失匹配
  3. 若用了 last,重写后会重新走一遍 location 匹配流程;用 break 则跳过后续 location 查找,直接处理当前块内指令(如 rootproxy_pass

location 块里的 rewrite:精准控制、按需触发

只有请求真正匹配到该 location 时,里面的 rewrite 才会执行。这是最常用、最安全的写法。

  1. 想把 /old/page.html 内部映射到 /new/page.html,就写在 location /old/ { ... }
  2. 推荐优先用 last:重写后重新匹配 location,利于模块化设计(例如统一由 location ~ .php$ 处理脚本)
  3. 避免在 if 块中嵌套 rewrite,尤其不要写 if ($request_uri ~* ...) —— Nginx 最新明确不推荐,易引发不可预期行为

flag 标志位选错,效果完全相反

rewrite 后面的 flag 不是可有可无的修饰,它直接决定是“浏览器跳转”还是“服务器内部重写”。

  1. permanentredirect:返回 301/302,地址栏会变,适合域名迁移或 SEO 调整
  2. last:URI 改写后,立刻用新路径再找一次 location,适合路径标准化或路由转发
  3. break:URI 改写后,停止 location 搜索,直接执行当前块剩余指令,适合简单路径补全(如加前缀)
  4. 漏写 flag 时默认是 last,但显式写出更清晰、更可控

排查规则不生效的三个关键点

很多 rewrite 看似配置了却不触发,问题往往出在请求根本没走到那块配置里。

  1. 确认请求是否命中正确的 server 块:检查 listen 端口、server_name 和 SNI 设置,HTTPS 场景下尤其注意 default_server 是否遗漏
  2. 验证 location 是否真被选中:用 add_header X-Location-Hit "yes";return 200 "in /api/"; 快速验证实际进入的是哪个块
  3. 留意正则优先级陷阱:比如 location ^~ /static/ 会屏蔽掉后面所有 location ~ .js$,即使 JS 文件在 /static/ 下也不会进正则块

相关文章

精彩推荐