proxy_pass和location匹配路径的拼接逻辑
在 Nginx 中,proxy_pass
后的服务地址与 location
匹配路径的拼接逻辑,核心取决于两个因素:location
定义的匹配路径格式 和 proxy_pass
目标地址是否以 /
结尾。以下分场景详细说明:
场景1:location
使用前缀匹配(最常见)
前缀匹配是指 location
以路径开头(不含正则符号 ~
~*
^~
等),例如 location /api/
或 location /api
。
子场景1.1:proxy_pass
目标地址不带 /
结尾
此时,Nginx 会将 完整的客户端请求 URI 拼接到 proxy_pass
地址后。
示例:
location /api/ {proxy_pass http://backend; # 目标地址不带 /
}
- 客户端请求:
/api/user
- 转发地址:
http://backend/api/user
(完整 URI 直接拼接)
子场景1.2:proxy_pass
目标地址带 /
结尾
此时,Nginx 会先去掉 location
匹配到的路径部分,再将剩余的 URI 拼接到 proxy_pass
地址后。
示例:
location /api/ {proxy_pass http://backend/; # 目标地址带 /
}
- 客户端请求:
/api/user
- 匹配到的
location
路径是/api/
,去掉后剩余 URI 为user
- 转发地址:
http://backend/user
特殊情况:location
路径不带 /
(如 location /api
)
若 location
定义为 location /api
(末尾无 /
),匹配逻辑会略有不同:
- 它会匹配以
/api
开头的所有请求(包括/api
、/api/
、/api/user
等)。
示例1:
location /api {proxy_pass http://backend; # 不带 /
}
- 客户端请求:
/api/user
- 转发地址:
http://backend/api/user
(完整 URI 拼接)
示例2:
location /api {proxy_pass http://backend/; # 带 /
}
- 客户端请求:
/api/user
- 匹配到的
location
路径是/api
,去掉后剩余 URI 为/user
- 转发地址:
http://backend/user
场景2:location
使用精确匹配(=
前缀)
精确匹配(location = /path
)仅匹配与路径完全一致的请求,拼接逻辑同样受 proxy_pass
是否带 /
影响。
示例1:
location = /api { # 仅匹配 /api 请求proxy_pass http://backend; # 不带 /
}
- 客户端请求:
/api
- 转发地址:
http://backend/api
示例2:
location = /api {proxy_pass http://backend/; # 带 /
}
- 客户端请求:
/api
- 转发地址:
http://backend/
(因location
匹配的/api
被去掉,剩余为空,直接拼接/
)
场景3:location
使用正则匹配(~
或 ~*
)
正则匹配(如 location ~ ^/api/(\d+)$
)时,proxy_pass
后不能包含路径(只能是主机或 IP:端口),否则 Nginx 会报错。
此时,Nginx 会将完整的客户端请求 URI 直接拼接到 proxy_pass
地址后。
示例:
location ~ ^/api/(\d+)$ { # 匹配 /api/123 这类请求proxy_pass http://backend; # 注意:这里不能加 / 或其他路径
}
- 客户端请求:
/api/123
- 转发地址:
http://backend/api/123
总结核心规律
proxy_pass
地址不带/
结尾:转发时拼接完整客户端请求 URI。proxy_pass
地址带/
结尾:转发时先去掉location
匹配的路径部分,再拼接剩余 URI。- 正则匹配的
location
:proxy_pass
后不能有路径,直接拼接完整 URI。
通过调整 proxy_pass
是否带 /
,可以灵活控制转发路径的拼接方式,解决实际场景中“多一级目录”或“少一级目录”的问题。