rewrite 去除 URL 前缀的核心是正则匹配捕获路径、替换并用 break 终止重写,确保 location 精准匹配原始请求;它比 proxy_pass 斜杠方案更灵活,支持动态前缀、条件判断和复杂路径改写。

用 rewrite 去除 URL 中的指定前缀,核心是正则匹配 + 路径替换,再配合 break 防止循环重写。它不依赖 proxy_pass 的斜杠机制,逻辑更直观,也更适合复杂规则或需要条件判断的场景。
基础写法:匹配并捕获剩余路径
假设要将 /api/user/xxx 改为 /xxx,转发给后端:
location /api/user/ {rewrite ^/api/user/(.*)$ /$1 break;proxy_pass http://backend;}
说明:^/api/user/(.*)$ 精准匹配以 /api/user/ 开头的路径,并把后面所有内容捕获到 $1;/$1 就是去掉前缀后的结果;break 表示重写后停止当前 location 内的后续匹配,直接走 proxy_pass。
注意 rewrite 的执行时机和 location 匹配关系
rewrite 在 location 块内执行,但它的效果发生在请求进入该 location 之后、proxy_pass 之前。因此:
- 必须确保
location能准确匹配带前缀的原始请求,比如用location /myapp/ { ... },而不是location / { ... }(后者可能被优先匹配,导致 rewrite 不生效) - 如果用了
last(而非break),Nginx 会重新发起内部请求,再次匹配 location,容易引发循环或跳转到错误块 - 避免在同一个 location 中混用多个 rewrite,除非明确理解它们的执行顺序和覆盖关系
进阶用法:保留查询参数、处理根路径
真实请求常带查询参数(如 /api/v1/users?id=123),基础写法默认会丢失 $args。安全做法是显式拼接:
rewrite ^/api/v1/(.*)$ /$1?$args break;
另外,若前缀可能出现在路径末尾(如 /api/v1/ 本身),需防止重写为空路径。可加条件判断或使用更严谨的正则:
-
rewrite ^/api/v1/(.+)$ /$1?$args break;(.+要求至少一个字符,排除纯前缀) - 或单独处理空路径:
if ($uri = "/api/v1/") { return 301 /; }
与 proxy_pass 斜杠方案对比选型
如果只是简单去前缀,proxy_pass http://backend/;(末尾带斜杠)更轻量、无需正则,性能略优;但 rewrite 更灵活:
- 支持动态前缀(如版本号
/v1/、/v2/统一剥离) - 可结合
if或 NJS 做条件控制(例如只对特定 header 或 User-Agent 生效) - 能改写为完全不同的路径结构,不止是“剪前缀”


















