1.本文内容
使用反向代理解决请求跨域问题,以及如何利用请求参数配置一个动态反向代理
2.问题场景
公司有一个“文档接口服务”,用来维护公司所有项目的接口文档。
现假定:
接口文档地址:http://192.168.1.100:8080/doc
项目接口地址:http://192.168.1.200:8090/api
接口文档和项目不在同一个服务器且端口都不相同,出现了跨域的问题,接口无法正常模拟。
ps:什么是跨域?当一个请求url的协议、域名(IP)、端口三者之间任意一个与当前页面url不同即为跨域。
在不改动接口服务代码的情况下,使用nginx反向代理来解决跨域,方式如下
2.1.nginx反向代理
- 在192.168.1.100(接口文档服务器)安装nginx,监听8081端口
- 将
/doc
请求代理到http://192.168.1.100:8080/doc
- 将
/api
请求代理到http://192.168.1.200:8090/api
具体配置如下:
server {
listen 8081;
server_name localhost;
# 代理应用服务接口
location /api {
proxy_pass http:192.168.1.200:8090/api;
}
# 代理文档服务
location /doc {
proxy_pass http://192.168.1.100:8080/doc;
}
}
- 此后我们就需要通过代理地址访问“接口文档服务”了:
http://192.168.1.100:8081/doc
;
我们接口文档中原本的接口地址也需要做相应的修改
例:http://192.168.1.200:8090/api/login
现在要改为http://192.168.1.100:8081/api/login
此时我们的所有操作都在http://192.168.1.100:8081/
服务完成,跨域问题解决。
2.2.nginx动态反向代理(根据请求的参数进行动态配置代理)
“接口文档服务”肯定不止维护一个项目的接口文档,如果还按照2.1
中进行配置,那么项目多了维护成本就很高,此时就考虑使用动态的方式去做。
配置如下:
server {
listen 8081;
server_name localhost;
location /doc {
if ( $arg_url != "" ) {
proxy_pass $arg_url;
}
proxy_pass http://192.168.1.100:8080/doc;
}
}
-
nginx关键字:
$arg_
$arg_
可以获取到请求路径中的参数值,
比如:http://192.168.1.100:8081/doc?url=abc
$arg_url
就能获取到abc
-
nginx关键字:
if
if
判断是否有url参数,如果有则直接转发到url地址,如果没有则正常转发到“接口文档服务” -
接口地址拼接(重点)
动态反向代理后,接口地址就需要两部分,
第一部分是固定的,就是“接口文档服务”的代理地址http://192.168.1.100:8081/doc?url=
第二部分是真实的业务接口地址,比如:http://192.168.1.200:8090/api/login
接口文档的完整地址就是:http://192.168.1.100:8081/doc?url=http://192.168.1.200:8090/api/login
注意事项:
1.location /doc {
这个/doc
不能写成/doc/
会有奇怪的问题,有兴趣的可以研究下。
2.if
需要补充对应的空格,否则会报错