Nginx系列-4 proxy_pass使用和路径拼接问题

1.proxy_pass使用

proxy_pass指令用于请求的转发,请客户端请求转发至第三方服务器;如下所示:

复制代码
location /query {
	proxy_pass http://www.baidu.com;
}

上述案例将以/query开头的url请求转发至http://www.baidu.com.

proxy_pass用法较为简单,但使用时路径拼接问题需要重点关注,也是本章节的重点,以下通过案例的方案进行介绍和验证。
基准用例准备:

说明:路径拼接问题出现在前缀匹配上,完全匹配和正则表达式匹配不存在该问题。因此,可以借助完全匹配作为基准测试用例。

在8888端口上监听四个完全匹配路径:

shell 复制代码
server {
    server_name localhost;
    listen 8888;

     location = /test.html {
        return 200 "enter /test.html  ";
     }

    location = /proxy/test.html {
        return 200 "enter /proxy/test.html  ";
     }

     location = /ewen/test.html {
        return 200 "enter /ewen/test.html  ";
     }

     location = /ewentest.html {
        return 200 "enter /ewentest.html  ";
     }
}

测试结果如下所示:

shell 复制代码
[root@124 conf]# curl http://localhost:8888/test.html
enter /test.html  

[root@124 conf]# curl http://localhost:8888/proxy/test.html
enter /proxy/test.html 

[root@124 conf]# curl http://localhost:8888/ewen/test.html
enter /ewen/test.html  

[root@124 conf]# curl http://localhost:8888/ewentest.html
enter /ewentest.html  

问题来源:

shell 复制代码
location /代理url部分 {
	proxy_pass http://目标url部分
}

代理url部分是否以/结尾,以及目标url是否携带子路径和是否已/结尾等因素,可以将location /proxy {proxy_pass http://localhost:8888;}`组合形成8种场景:

shell 复制代码
#case1: 代理url部分不以/结尾,目标url没有子路径且不以/结尾
location /proxy {
	proxy_pass http://localhost:8888;
}
#case2: 代理url部分不以/结尾,目标没有子路径且url以/结尾
location /proxy {
	proxy_pass http://localhost:8888/;
}

#case3: 代理url部分以/结尾,目标url没有子路径且不以/结尾
location /proxy/ {
	proxy_pass http://localhost:8888;
}
#case4: 代理url部分以/结尾,目标url没有子路径,以/结尾
location /proxy/ {
	proxy_pass http://localhost:8888/;
}


#case5: 代理url不以/结尾,目标url存在子路径且不以/结尾
location /proxy {
	proxy_pass http://localhost:8888/ewen;
}
#case6: 代理url不以/结尾,目标url存在子路径且以/结尾
location /proxy {
	proxy_pass http://localhost:8888/ewen/;
}

#case7: 代理url以/结尾,目标url存在子路径且不以/结尾
location /proxy/ {
	proxy_pass http://localhost:8888/ewen;
}
#case8: 代理url以/结尾,目标url存在子路径且以/结尾
location /proxy/ {
	proxy_pass http://localhost:8888/ewen/;
}

当执行http://localhost:8001/proxy/test.html请求后,上述8种情况的访问路径为:

http://localhost:8888 http://localhost:8888/ http://localhost:8888/ewen http://localhost:8888/ewen/
/proxy/ http://localhost:8888/proxy/test.html http://localhost:8888/test.html http://localhost:8888/ewentest.html http://localhost:8888/ewen/test.html
/proxy http://localhost:8888/proxy/test.html http://localhost:8888/test.html http://localhost:8888/ewen/test.html http://localhost:8888/ewen//test.html

结论:

1\] 如果目标url仅包括ip和端口(没有斜线和子路径),如http://localhost:8888形式,则仅替换协议、域名和端口部分,其他路径保持不变: 如上述案例中: ```shell location /proxy/ { proxy_pass http://localhost:8888; } 和 location /proxy { proxy_pass http://localhost:8888; } 场景下,访问http://localhost:8001/proxy/test.html 都会转发到http://localhost:8888/proxy/test.html ``` \[2\] 其他场景,客户端的请求的url路径删除协议-域名-端口后,进行代理url的剪切,将剪切后的部分直接拼接到目标url尾部,以下以案例进行过程说明。 访问http://localhost:8001/proxy/test.html时: 如果location定义为: ```shell location /proxy { proxy_pass http://localhost:8888/ewen; } ``` http://localhost:8001/proxy/test.html删除协议-域名-端口部分后,得到/proxy/test.html; /proxy/test.html 删除代理url后,得到/test.html; /test.html拼接至目标url即http://localhost:8888/ewen后,得到http://localhost:8888/ewen/test.html. 如果location定义为: ```shell location /proxy/ { proxy_pass http://localhost:8888/ewen; } ``` http://localhost:8001/proxy/test.html删除协议-域名-端口部分后,得到/proxy/test.html; /proxy/test.html 删除代理url后,得到test.html; test.html拼接至目标url即http://localhost:8888/ewen后,得到http://localhost:8888/ewentest.html.

相关推荐
HalvmånEver4 分钟前
Linux:库制作与原理(四)
linux·运维·服务器
小白学大数据5 分钟前
构建新闻数据爬虫:自动化提取与数据清洗技巧
运维·爬虫·python·自动化
leo_23218 分钟前
从开发语言角度来谈谈SMP(下)--SMP(软件制作平台)语言基础知识之十三
linux·运维·开发语言·开发工具·smp(软件制作平台)·应用系统
咕噜企业分发小米21 分钟前
Linux嵌入式系统在智能家居中的具体应用案例有哪些?能否详细介绍其技术实现?
linux·运维·智能家居
为自己_带盐24 分钟前
记一次“丝滑”的服务器迁移
运维·服务器
ん贤25 分钟前
io.copy
运维·服务器·网络·io.copy
默|笙26 分钟前
【Linux】进程控制(2)进程等待
linux·运维·服务器
jockerzoo@31 分钟前
IP 定向灰度发布:ArgoCD + GitLab CLI 方案
运维
乾元32 分钟前
红队 / 蓝队:用 AI 自动生成攻击场景并评估防御效果——从“安全演练”到“可计算的网络对抗系统”
运维·网络·人工智能·网络协议·安全·web安全·架构
半路_出家ren34 分钟前
Python操作MySQL(详细版)
运维·开发语言·数据库·python·mysql·网络安全·wireshark