前端开发过程中,我们为了避免与后端进行接口联调时反复修改请求地址,通常会采用服务器地址相对路径的方法,以../rest/api/
的模式请求前端文件所在服务器的http://192.168.1.100/rest/api
接口。这样可以规避开发阶段(develop
)和生产阶段(production
)代码不一致的问题,但是在接口联调阶段(debug
),特别是前后端由不同的人开发的情况下,则需要使用代理服务器进行转发。
一、问题所在
通常情况下我们的nginx配置如下
1 2 3 4 5 6 7 8 9 10 11 12
| server { listen 80; server_name localhost;
location / { root D:\project\branch; }
location /rest/api/ { proxy_pass http://192.168.1.100/rest/api/; } }
|
在接口复杂的情况下,我们的location
匹配地址可能会出现较多个。而且因为工作需要,我们可能会同时与多个后台开发者进行接口联调,那么可能会出现如下的nginx配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| server { listen 80; server_name localhost;
location / { root D:\project\branch; }
location /rest/api/ { proxy_pass http://192.168.1.100/rest/api/; #proxy_pass http://192.168.1.101/rest/api/; }
location /rest2/api2/ { proxy_pass http://192.168.1.100/rest2/api2/; #proxy_pass http://192.168.1.101/rest/api/; }
location /rest3/api3/ { proxy_pass http://192.168.1.100/rest3/api3/; #proxy_pass http://192.168.1.101/rest/api/; } }
|
二、修改方法
为了工作方便,我们可能会将不同后台开发人员的地址以注释的方式记录在nginx配置文件内,需要切换后台服务器时,修改配置项中的注释内容,然后执行nginx -s reload
来重启nginx服务。
那么,既然配置文件中有大量的重复地址信息,比如http://192.168.1.100
,我们是不是可以把它提取出来作为nginx变量呢?然后proxy_pass
读取它,这样在修改文件时只需要修改一个地方即可。
按照如下方式进行测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| server { listen 80; server_name localhost;
set $host '192.168.1.100'; #set $host '192.168.1.101';
location / { root D:\project\branch; }
location /rest/api/ { proxy_pass http://$host/rest/api/; }
location /rest2/api2/ { proxy_pass http://$host/rest2/api2/; }
location /rest3/api3/ { proxy_pass http://$host/rest3/api3/; } }
|
重启服务后,nginx不报错,但是代理无效,无法访问。接着使用geo
、map
,均无法正常进行代理转发。
最后发现可以使用upstream
模式实现此项功能,修改后的配置文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| upstream host { server 192.168.1.100; #server 192.168.1.101; }
server { listen 80; server_name localhost;
location / { root D:\project\branch; }
location /rest/api/ { proxy_pass http://host; }
location /rest2/api2/ { proxy_pass http://host; }
location /rest3/api3/ { proxy_pass http://host; } }
|
再次精简一点,采用正则匹配的方式进行修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| upstream host { server 192.168.1.100; #server 192.168.1.101; }
server { listen 80; server_name localhost;
location / { root D:\project\branch; }
location ~ /rest(.*)/api(.*)/ { rewrite /rest(.*)/api(.*)/ /rest$1/api$2/ break; proxy_pass http://host; } }
|
这样采用正则匹配方式后,不仅可以匹配原有的/rest1/api1/
、/rest2/api2/
、/rest3/api3/
,还可以匹配诸如/project/rest1/api1/
等等前面含有项目文件路径的location
。
等后期有时间,再研究一下nginx的rewrite
、upstream
详细使用方法。
参考文献
proxy_set_header设置Host为$proxy_host,$host与$local_host的区别
Nginx中的proxy_pass和rewrite