前言
在 Nginx 的日常使用中,经常需要反向代理一些接口,而接口和 location 的末尾斜杠和匹配问题,由于可能性太多,常常弄混,故写此文记录之。
proxy_pass 不带目录
后端接口:http://192.168.0.180:8080/api/default
前端请求:http://192.168.0.180:80/demo/api/default
第一种
location 末尾不带斜杠,proxy_pass 末尾不带斜杠
nginx 配置
server {
listen 80;
location /demo {
proxy_pass http://127.0.0.1:8080;
}
}
实际访问:http://192.168.0.180:8080/demo/api/default
结论:location 和 proxy_pass 都不带斜杠,实际访问地址 = proxy_pass + location + /api/default
第二种
location 末尾带斜杠,proxy_pass 末尾不带斜杠
nginx 配置
server {
listen 80;
location /demo/ {
proxy_pass http://127.0.0.1:8080;
}
}
实际访问:http://192.168.0.180:8080/demo/api/default
结论:和第一种情况一致。
第三种
location 末尾不带斜杠,proxy_pass 末尾带斜杠
nginx 配置
server {
listen 80;
location /demo {
proxy_pass http://127.0.0.1:8080/;
}
}
实际访问:http://192.168.0.180:8080//api/default
结论:proxy_pass 末尾带斜杠时,就不会拼接 location 的代理路径了,但是会多出来一个斜杠,实际访问地址 = proxy_pass + /api/default,由于 proxy_pass 末尾带一个斜杠,而 /api/default 又以斜杠开头,导致中间存在两个斜杠。
第四种
location 末尾带斜杠,proxy_pass 末尾带斜杠
nginx 配置
server {
listen 80;
location /demo/ {
proxy_pass http://127.0.0.1:8080/;
}
}
实际访问:http://192.168.0.180:8080/api/default
结论:只有第四种,能够正常访问到后端接口,因为 proxy_pass 末尾带斜杠,所以不会拼接 location 的代理路径,并且 /demo/api/default 由于 location 是 /demo/,所以 api 前面的 / 被去掉了,接口变成 api/default,就不会出现第三种方案中的两个斜杠的问题,实际访问地址 = proxy_pass + api/default
表格
location | proxy_pass | 前端访问路径 | 实际访问路径 | 结果 |
---|---|---|---|---|
/demo | http://127.0.0.1:8080 | http://192.168.0.180:80/demo/api/default | http://192.168.0.180:8080/demo/api/default | 失败 |
/demo/ | http://127.0.0.1:8080 | http://192.168.0.180:80/demo/api/default | http://192.168.0.180:8080/demo/api/default | 失败 |
/demo | http://127.0.0.1:8080/ | http://192.168.0.180:80/demo/api/default | http://192.168.0.180:8080//api/default | 失败 |
/demo/ | http://127.0.0.1:8080/ | http://192.168.0.180:80/demo/api/default | http://192.168.0.180:8080/api/default | 成功 |
proxy_pass 带目录
后端接口:http://192.168.0.180:8080/api/default
前端请求:http://192.168.0.180:80/demo/api/default
第五种
location 末尾不带斜杠,proxy_pass 末尾不带斜杠
nginx 配置
server {
listen 80;
location /demo {
proxy_pass http://127.0.0.1:8080/api;
}
}
实际访问:http://192.168.0.180:8080/api/api/default
结论:和第一种不一样,尽管 location 和 proxy_pass 末尾都不带斜杠,但是 location 的代理路径并不会拼接到 proxy_pass 后面,实际访问地址 = proxy_pass + /api/default。
第六种
location 末尾带斜杠,proxy_pass 末尾不带斜杠
nginx 配置
server {
listen 80;
location /demo/ {
proxy_pass http://127.0.0.1:8080/api;
}
}
实际访问:http://192.168.0.180:8080/apiapi/default
结论:和第五种很相似,不过由于 location 末尾带了斜杠将 /api/default 前面的斜杠给去掉了,实际访问路径 = proxy_pass + api/default。
第七种
location 末尾不带斜杠,proxy_pass 末尾带斜杠
nginx 配置
server {
listen 80;
location /demo {
proxy_pass http://127.0.0.1:8080/api/;
}
}
实际访问:http://192.168.0.180:8080/api//api/default
结论:和第五种很相似,不过由于 proxy_pass 末尾带了斜杠,所以导致出现了第三种情况类似的问题,有两个重复的斜杠,实际访问路径 = proxy_pass + /api/default。
第八种
location 末尾带斜杠,proxy_pass 末尾带斜杠
nginx 配置
server {
listen 80;
location /demo/ {
proxy_pass http://127.0.0.1:8080/api/;
}
}
实际访问:http://192.168.0.180:8080/api/api/default
结论:和第五种的结果一致,实际访问路径 = proxy_pass + api/default。
表格
location | proxy_pass | 前端访问路径 | 实际访问路径 | 结果 |
---|---|---|---|---|
/demo | http://127.0.0.1:8080/api | http://192.168.0.180:80/demo/api/default | http://192.168.0.180:8080/api/api/default | 失败 |
/demo/ | http://127.0.0.1:8080/api | http://192.168.0.180:80/demo/api/default | http://192.168.0.180:8080/apiapi/default | 失败 |
/demo | http://127.0.0.1:8080/api/ | http://192.168.0.180:80/demo/api/default | http://192.168.0.180:8080/api//api/default | 失败 |
/demo/ | http://127.0.0.1:8080/api/ | http://192.168.0.180:80/demo/api/default | http://192.168.0.180:8080/api/api/default | 失败 |
proxy_pass 总结
proxy_pass 的参数分为以下三类:
- http://ip:port
- http://ip:port/
- http://ip:port/dir
如果按照 port 后面是否还跟着字符串来分,第二类和第三类可以合并成一类:
- port 后面不跟任何字符串
- port 后面还跟着字符串
对于第一类,实际访问路径 = proxy_pass + 匹配的代理路径
对于第二类,实际访问路径 = proxy_pass + 匹配的代理路径(删除 location 参数)
参考
- https://blog.csdn.net/weishuai90/article/details/131133621
- https://blog.csdn.net/s827292890/article/details/129583746