nginx反向代理中rewrite修改uri需在proxy_pass前执行且用break终止本location内后续rewrite;proxy_pass末尾斜杠决定路径拼接方式:带/则替换匹配部分,不带则原样转发;典型应用如剥离/api/前缀并分发至不同后端。

在 Nginx 反向代理中,用 rewrite 修改请求 URI 路径,核心是让重写发生在 proxy_pass 之前,并确保修改后的路径能被正确拼接到后端地址。关键不在“能不能改”,而在“怎么改才不丢路径、不循环、不转发错”。
rewrite 必须放在 location 块内,且明确控制执行流程
rewrite 指令只在当前 location 中生效,且默认在 proxy_pass 前执行。但它的行为受 flag 控制:
-
用
break最常见:重写 URI 后停止本 location 内其他 rewrite,继续执行 proxy_pass;适合路径前缀剥离,比如把/api/v2/xxx改成/v2/xxx再转发 -
避免用
last:它会重新匹配 location,容易触发循环(尤其当 location 是/或泛匹配时);除非你真需要多轮重写+再匹配 -
不用
redirect或permanent:这两个是发 302/301 给浏览器跳转,不是内部路径改写,和反向代理转发无关
proxy_pass 末尾斜杠决定路径拼接逻辑
rewrite 后的路径如何与 proxy_pass 组合,取决于 proxy_pass 是否以 / 结尾:
-
proxy_pass http://backend/(带结尾斜杠):Nginx 会用 rewrite 后的完整 URI 替换掉原 location 匹配部分,再拼到 backend 后面。例如:
location /api/ { rewrite ^/api/(.*)$ /$1 break; proxy_pass http://backend/; }
请求/api/users→ rewrite 成/users→ 转发到http://backend/users - proxy_pass http://backend(不带斜杠):Nginx 直接把原始请求路径(含 location 前缀)原样转发。此时 rewrite 若没配合 break,可能无效;必须靠 rewrite 显式改路径,并用 break 阻止后续干扰
典型场景:统一入口 + 多后端路由分发
前端所有 API 都走 /api/,但不同子路径要转发到不同服务,且需清理前缀:
location /api/auth/ { rewrite ^/api/auth/(.*)$ /$1 break; proxy_pass http://auth-srv/; }-
location /api/data/ { rewrite ^/api/data/(.*)$ /v1/$1 break; proxy_pass http://data-srv/; }(顺便升级 v1 版本路径) -
location /api/ { proxy_pass http://fallback-srv/; }(兜底,不重写,直接转发全路径)
调试建议:先确认 $uri 和 $request_uri 的区别
rewrite 操作的是 $uri(不含参数的路径),而 $request_uri 包含完整路径+查询串。如果需要保留参数,不用额外处理——Nginx 默认透传。可临时加日志验证:
log_format debug '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$uri" "$request_uri"';











