Nginx的这种反向代理用法,主要有如下两种情况,这里仅列出整个配置中的server部分,第一种情况请看如下配置:
server {
server_name www.abc.com;
location /uri/ {
proxy_pass http://192.168.99.100:8000;
}
}
nginx的proxy_pass对于此种情况的处理方式是:将location中的uri传递给后端服务器,也就是当客户端访问http://www.abc.com/uri/iivey.html 时,会被反向代理到http://192.168.99.100:8000/uri/iivey.html 进行访问。
第二种uri代理方式配置如下:
server {
server_name www.abc.com;
location /uri/ {
proxy_pass http://192.168.99.100:8000/new_uri/;
}
}
nginx的proxy_pass对于此种情况的处理方式是:替换成proxy_pass指令中URL中含有的uri,也就是当客户端访问http://www.abc.com/uri/iivey.html 时,会被反向代理到http://192.168.99.100:8000/new_uri/iivey.html 进行访问。
其实还有一种uri代理方式,配置如下:
server {
server_name www.abc.com;
location /uri/ {
proxy_pass http://192.168.99.100:8000/;
}
}
nginx的proxy_pass对于此种情况的处理方式是:替换成proxy_pass指令中URL中含有的uri,也就是当客户端访问http://www.abc.com/uri/iivey.html 时,会被反向代理到http://192.168.99.100:8000/iivey.html 进行访问。
这种反向代理方式其实是上面第二种uri代理方式的扩展,这里要重点注意下“proxy_pass http://192.168.99.100:8000/;” 这个url结尾有个“/”和没有”/”的区别。
三种情况的对比表
| 情况 | proxy_pass 配置 | 请求 /uri/file.html 转发到 | 规则 |
|---|---|---|---|
| 1 | http://192.168.99.100:8000 | http://192.168.99.100:8000/uri/file.html | 保留原 URI(location 路径附加) |
| 2 | http://192.168.99.100:8000/new_uri/ | http://192.168.99.100:8000/new_uri/file.html | 替换(用 /new_uri/ 替换 /uri/) |
| 3 | http://192.168.99.100:8000/ | http://192.168.99.100:8000/file.html | 去掉前缀(用 / 替换 /uri/) |
把 location /uri/ 想象成一件衣服:
| 配置 | 比喻 | 结果 |
|---|---|---|
proxy_pass http://backend; | 不换衣服 | 穿着 /uri/ 去后端 |
proxy_pass http://backend/new/; | 换上新衣服 | 脱掉 /uri/,穿上 /new/ |
proxy_pass http://backend/; | 脱掉衣服 | 脱掉 /uri/,什么都不穿 |
一、核心区别就一句话
带 / 会替换,不带 / 会保留
二、用生活例子理解
想象你是一家快递公司(Nginx),要把包裹(请求)转发到不同的仓库(后端):
情况1:不带 /(保留原地址)
location /北京/ {
proxy_pass http://仓库A; # 没有斜杠
}
- 包裹地址:
/北京/朝阳区/ - 转发到仓库A后地址:还是
/北京/朝阳区/✅
情况2:带 /(替换地址)
location /北京/ {
proxy_pass http://仓库A/; # 有斜杠
}
- 包裹地址:
/北京/朝阳区/ - 转发到仓库A后地址:变成
/朝阳区/(/北京/被替换掉了)✅
三、直接看例子(最清楚)
假设请求都是:http://example.com/api/user/list
例1:不带 /(保留)
location /api/ {
proxy_pass http://192.168.1.10:8080;
}
🔍 转发结果:http://192.168.1.10:8080/api/user/list
/api/原封不动带过去了
例2:带 /(替换)
location /api/ {
proxy_pass http://192.168.1.10:8080/;
}
🔍 转发结果:http://192.168.1.10:8080/user/list
/api/被替换成/了
例3:带其他路径(自定义替换)
location /api/ {
proxy_pass http://192.168.1.10:8080/newapi/;
}
🔍 转发结果:http://192.168.1.10:8080/newapi/user/list
/api/被替换成/newapi/
四、用表格对比(一目了然)
| 请求路径 | proxy_pass 配置 | 转发到后端的路径 |
|---|---|---|
/api/user | http://backend | /api/user |
/api/user | http://backend/ | /user |
/api/user | http://backend/v2/ | /v2/user |
/api/v1/user | http://backend | /api/v1/user |
/api/v1/user | http://backend/ | /v1/user |
五、实际应用场景
场景1:后端没有 /api 前缀
# 后端接口是 /user/list,不是 /api/user/list
location /api/ {
proxy_pass http://192.168.1.10:8080/; # 用斜杠去掉 /api
}
# 请求 /api/user/list → 转发到 /user/list ✅
场景2:后端有不同前缀
# 后端接口是 /v2/user/list
location /api/ {
proxy_pass http://192.168.1.10:8080/v2/; # 把 /api 换成 /v2
}
# 请求 /api/user/list → 转发到 /v2/user/list ✅
场景3:保持原样
# 后端接口就是 /api/user/list
location /api/ {
proxy_pass http://192.168.1.10:8080; # 不加斜杠,保持原样
}
# 请求 /api/user/list → 转发到 /api/user/list ✅
六、记忆口诀
斜杠是剪刀,剪掉匹配的部分
- 不加斜杠:原封不动转发
- 加斜杠:剪掉 location 匹配的部分
- 加路径:剪掉后换上新的
七、验证方法
想知道到底转发到哪了,加个响应头看看:
location /api/ {
proxy_pass http://192.168.1.10:8080/;
add_header X-Debug-Path $upstream_addr$request_uri; # 看实际转发的路径
}
然后用 curl -I 看响应头里的 X-Debug-Path
发表回复