rewrite 与 proxy_pass 配合需用 break 终止重写并执行转发;正则 location 中 rewrite 提取变量后拼路径,proxy_pass 仅写协议+主机;rewrite 后路径须以 / 开头,避免 302 或 404。

rewrite 和 proxy_pass 配合使用能处理动态路径、版本路由、前缀剥离等复杂场景,但必须理清执行顺序和 flag 作用——rewrite 在 location 内生效后,需用 break 才能让 proxy_pass 正常执行;否则 proxy_pass 会被跳过。
rewrite + proxy_pass 的执行逻辑
location 块内同时出现 rewrite 和 proxy_pass 时:
- rewrite 默认不带 flag 时,会触发内部重定向,导致再次进入 server 块匹配新 URI,proxy_pass 不执行
- 加 break:终止当前 location 内后续 rewrite,并继续执行本 location 中的 proxy_pass
- 加 last:重写后立即跳出当前 location,重新匹配 location,proxy_pass 被忽略
- proxy_pass 后不能带路径(如
http://backend/api)时,rewrite 才能真正控制转发路径;若 proxy_pass 已含路径,则优先按 proxy_pass 规则裁剪
正则匹配下路径重写(推荐做法)
当需要提取版本号、模块名等动态段时,必须用正则 location + rewrite break:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- location 必须用
~或~*开头,例如location ~ ^/api/(?<v>v\d+)/(.*)$</v> - proxy_pass 只能写协议+主机(如
http://127.0.0.1:5000),结尾不能带路径,否则配置报错 - rewrite 中用命名捕获组提取变量,再拼成目标路径,末尾加 break
- 示例:
rewrite ^/api/(?<v>v\d+)/(.*)$ /$v/$2 break;</v>,请求/api/v3/users→ 重写为/v3/users→ 转发给后端
避免常见错误的实操要点
这些细节出错会导致 404、路径多斜杠、循环代理或静默失效:
- rewrite 后的路径必须以
/开头,否则 proxy_pass 会把它当作相对路径拼接,引发异常 - 不要在 rewrite 中写完整 URL(如
https://...),那会强制 302 跳转,与反向代理目标冲突 - 若需保留原始路径中某段(如 /openam/),proxy_pass 结尾必须带
/,且 location 匹配要精确(如location /openam/) - 调试时开启
error_log /path/to/log notice;,观察 rewrite 和 proxy_pass 实际转发的 URI
一个典型实战配置
把 /legacy/app/* 映射为 /new/v2/app/*,并透传查询参数:
location ~ ^/legacy/(app/.*)$ {
rewrite ^/legacy/(app/.*)$ /new/v2/$1 break;
proxy_pass http://backend-svc;
proxy_set_header X-Original-URI $request_uri;
}
请求 /legacy/app/login?next=%2Fhome → 重写为 /new/v2/app/login?next=%2Fhome → 转发成功。










