nginx如何实现前后端分离的跨域问题

前文《如何解决前后端分离的跨域问题?》介绍了利用CORS标准可以解决前后端分离部署的跨域问题,另外一个非常常用的解决方案就是利用Nginx做反向代理。

Nginx是2004年伊戈尔·赛索耶夫(lgor Sysoev)为俄罗斯搜索引擎站点 Rambler.ru 设计开发的。2019年2月,NGINX取代Apache HTTPD,成为互联网上部署最广泛的服务器。从2004年发布至今,Nginx的功能已经非常丰富,可作为HTTP服务器,可配置服务端的负载均衡,也可作为反向代理服务器。

Nginx的开发者 lgor Sysoev,后来创办了Nginx公司

什么是反向代理

有反向,一定有正向,那么先来看一下什么是正向代理。有一个客户端想要访问一个服务器,但是它可能无法直接访问这台服务器,这时候就找可以访问目标服务器的另外一台服务器,而这台服务器就被当做是代理人的角色 ,称之为代理服务器。于是客户端把请求发给代理服务器,由代理服务器获得目标服务器的数据并返回给客户端。

正向代理

正向代理的代理服务器是为客户端作代理人,而反向代理就是代理服务器为服务器作代理人。常用的应用场景就是一些大型网站(比如百度)使用多台服务器分布式部署,可以解决访问人数较多带来的高并发问题。这时多台服务器就可以由一个反向代理服务器来代理,客户端发来的请求,先到达反向代理服务器,然后再按一定的规则分发到具体的服务器来处理。而对于客户端来说,它其实并不知道请求究竟是哪台服务器来处理的。

反向代理

Nginx反向代理

Nginx = Engine X

Nginx在做反向代理时,可以根据不同的正则匹配规则,采取不同的转发策略。对于前端和后端的程序可以定义不同的转发策略,对于客户端,也就是浏览器,无论访问前端页面还是后端接口,请求都是到达Nginx代理服务器,这样都是在同一个域内,不存在跨域问题了。

下面我们看一个Vue + Springboot前后端分离部署的例子。

vue项目通常都要构建成静态文件后再进行部署,构建命令如下:

npm run build

build之后会生成一个dist文件夹,其中包含一个index.html文件和一个static文件夹。

要解决跨域问题,思路就是要把前后端放在同一个域下面。当然直接的做法是将dist文件夹放在Springboot的static目录下,不过更常见的做法是用nginx配置反向代理。

以下是nginx的配置文件实例,配置文件通常在/etc/nginx/ 目录下的nginx.conf文件中,具体路径要看nginx的具体安装情况。

server { listen 443 ssl; server_name www.weishuo.com; ## for ssl config ... ... ## for gzip config ... ... location / { root /opt/app/front/dist; indexindex.html index.htm; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass :8001; } }

以上配置说明,如果访问前端页面,可以直接访问域名:。nginx会定位到部署在/opt/app/front目录下的dist文件夹。

在页面中涉及到后端请求,前端需要请求URI:/api

nginx会将对后端接口请求转发到服务器的8001端口上。

Nginx反向代理实现前后端分离

还有一种情况是以node服务器的形式来部署前端项目,这样前端项目启动后也会占用一个端口号。针对这种情况,前后端都需要通过proxy_pass指令进行转发。

假如前端项目部署在8001端口,后端服务部署在8002端口,可以按照以下nginx配置进行请求转发,解决跨域问题。

server { listen 80; server_name www.weishuo.com; location /front/ { proxy_pass :8001/; } location /api/ { proxy_pass :8002/; } }

请求转发如下图所示。

Nginx反向代理实现前后端分离

总结

本文我们介绍了nginx配置反向代理,可以解决前后端分离项目的跨域问题,严格说并不是解决跨域,而是通过请求转发规避了跨域问题。需要注意的一点是nginx的请求转发匹配规则。比如访问

第一种nginx配置

location /proxy/ { proxy_pass :8001/; }

nginx会将请求转发到 :8001/test.html

第二种nginx配置

location /proxy { proxy_pass :8001/; }

nginx会将请求转发到 :8001/proxy/test.html

配置规则只是相差了一个‘/’ 号,请求转发路径则完全不同。这一点在实际配置nginx过程中要格外注意。