现在很多公司都是区分内外网的,而从外网是无法直接访问内网部署的站点与API的,当一个部署在内网的站点(比如官网)需要向外部开放的时候就需要利用Nginx来进行代理转发。
以一个vue+springboot项目为例
【注】:本文假定前端以IP的形式访问后端api,例如:172.16.2.2:8081/a/b
外网(云)服务器IP:114.251.x.x
站点域名:a.aaa.com.cn(当前映射到172.16.2.1)
内网前端服务器IP:172.16.2.1
内网后端服务器IP:172.16.2.2
该项目的前后端都是部署在内网的,所以在内网直接访问不会有问题,而从外网访问当然也就访问不到。
步骤一:将域名在DNS上的IP映射由内网IP改为外网服务器IP,然后配置Nginx
将 a.aaa.com.cn 在DNS上的映射由内网IP(172.16.2.1)更改为外网服务器的IP(114.251.x.x),这样外网客户对 a.aaa.com.cn 的访问请求会被映射到 114.251.x.x 的80端口(域名映射到IP而不是端口,http默认访问80端口),而该服务器上的nginx会将打到80端口上的请求转发(配置监听转发即可)到内网前端服务器约定好的端口,比如 172.16.2.1:8080 ,这种方式可以通过80端口这一个外网端口用nginx把外网流量打到多个端口。
如果内网前端服务器上vue部署的tomcat/nginx监听的是8080端口,那这时已经可以通过域名访问到页面并看到页面的静态内容了。
但是请注意,当前是无法在前端直接以IP的形式(172.16.2.2:8081/a/b)调用api的,因为提供api的后端服务器是内网服务器,而此时在前端向后端发起的请求的host是a.aaa.com.cn(解析到外网IP),也就无法访问到后端服务器。
步骤二:更改vue中api请求形式,然后配置nginx
这一步的根本目的是改变请求的host。
假定原先vue中某个api的请求方式是 172.16.2.2:8081/a/b ,现在把它替换为 a.aaa.com.cn/a/b 。
const ipAddr = '172.16.2.2', domainAddr = 'a.aaa.com.cn';
export var demo = `${ipAddr}:8081/a/b` ===> export var demo = `${domainAddr}/a/b`
用这种域名的形式替换掉ip形式,把前端发出的请求打到前端172.16.2.1上唯一的公网端口,然后配置nginx,将路径为 /a/b 的请求转发到 172.16.2.2:8081/a/b 。这样,请求的host就从172.16.2.1变成了a.aaa.com.cn,这也就避免了内外网不通或是跨域的问题。
所以,整个过程的公网数据流向是:
外网域名 -> 外网服务器:80 -> 内网前端:8080(前端显示) -> (发出请求) -> 外网域名 -> 外网服务器:80 -> 内网前端:8080 -> nginx分发 -> 内网后端
(图片下面还有一种方案,也可以看一下)
数据流向补充另外一种类似的思路(未验证):
这种方案的根本目的也是通过代理的方式更改host
基于webpack的vue自带代理,可以直接用,就不需要额外配置代理了,否则用node.js写一个简单的express也可以。webpack的代理配置在/config/index.js中,示例配置如下:
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/a': {
target: 'http://172.16.2.2:8081',//目标接口地址
changeOrigin: true,//是否跨域
pathRewrite: {
'/a': '/a'//重写接口
}
}
}
这种方案理论上是可行的,而且更简单一些。然而手里暂时没有可以做验证的资源,后续验证了再来更新吧。
网友评论