使用 Nginx 部署先后端分离项目,解决跨域问题

先后端分离这个问题其实松哥和你们聊过不少了,上周松哥把本身的两个开源项目部署在服务器上以帮助你们能够快速在线预览(喜大普奔,两个开源的 Spring Boot + Vue 先后端分离项目能够在线体验了),而后群里就有小伙伴想让松哥来聊聊如何结合 Nginx 来部署先后端分离项目?今天咱们就来聊一聊这个话题。css

不得不说的跨域

不少人对先后端分离部署感到困惑,其实主要是困惑跨域问题怎么解决。由于先后端分离项目在开发的时候,前端经过 nodejs 来运行,须要一个单独的端口,后端经过 Tomcat 或者 Jetty 来运行,也须要端口,两个不一样的端口,就形成了跨域。html

可是松哥以前屡次和你们聊过这个问题,这种跨域并非咱们传统开发中真正的跨域,这个所谓的跨域只在开发环境中存在,生产环境下就不存在这个跨域问题了。因此咱们不能按照以往的经过 JSONP 或者 CORS 之类的手段来解决这个跨域问题。前端

先后端分离开发中,前端为了可以模拟出测试数据,而且模拟出请求,通常须要借助于 nodejs 来运行,这是开发时候的状态,开发时候的配置你们能够参考这篇文章:java

等开发完成后,咱们会对前端项目编译打包,编译打包完成以后,就只剩下一堆 js、css 以及 html 文件了,咱们把这些编译打包后的文件拷贝到后端项目中,这样再去运行就不存在跨域问题了(例如将编译打包后的静态文件拷贝到 Spring Boot 项目的 src/main/resources/static 目录下)。这种方式我就再也不多说了,相信你们都会,今天我们主要来看看如何结合 Nginx 来部署。node

Nginx 大杀器

结合 Nginx 来部署先后端分离项目算是目前的主流方案。一来部署方便,二来经过动静分离也能够有效提升项目的运行效率。nginx

你们知道咱们项目中的资源包含动态资源和静态资源两种,其中:小程序

  • 动态资源就是那些须要通过容器处理的资源,例如 jsp、freemarker、各类接口等。
  • 静态资源则是那些不须要通过容器处理,收到客户端请求就能够直接返回的资源,像 js、css、html 以及各类格式的图片,都属于静态资源。

将动静资源分开部署,能够有效提升静态资源的加载速度以及整个系统的运行效率。后端

在先后端分离项目部署中,咱们用 Nginx 来作一个反向代理服务器,它既能够代理动态请求,也能够直接提供静态资源访问。咱们来一块儿看下。建议你们先阅读松哥之前关于 Nginx 的一篇旧文,能够有效帮助你们理解后面的配置:跨域

后端部署

后端接口的部署,主要看项目的形式,若是就是普通的 SSM 项目,那就提早准备好 Tomcat ,在 Tomcat 中部署项目,若是是 Spring Boot 项目,能够经过命令直接启动 jar,若是是微服务项目,存在多个 jar 的话,能够结合 Docker 来部署(参考一键部署 Spring Boot 到远程 Docker 容器),不管是那种形式,对于咱们 Java 工程师来讲,这都不是问题,我相信这一步你们都能搞定。缓存

后端项目能够在一个非 80 端口上部署,部署成功以后,由于这个后端项目只是提供接口,因此咱们并不会直接去访问他。而是经过 Nginx 请求转发来访问这个后端接口。

松哥这里以我去年为一个律所的小程序为例,后端是一个 Spring Boot 工程,那么我能够经过 Docker 部署,也能够直接经过命令来启动,这里简单点,直接经过命令来启动 jar ,以下:

nohup java -jar jinlu.jar > vhr.log &

后端启动成功以后,我并不急着直接去访问后端,而是安装而且去配置一个 Nginx,经过 Nginx 来转发请求,Nginx 的基本介绍与安装,你们能够参考(Nginx 极简入门教程!),我这里就直接来讲相关的配置了。

这里咱们在 nginx.conf 中作出以下配置:

首先配置上游服务器:

upstream zqq.com{
  server 127.0.0.1:9999 weight=2;
}

在这里主要是配置服务端的地址,若是服务端是集群化部署,那么这里就会有多个服务端地址,而后能够经过权重或者 ip hash 等方式进行请求分发。

而后咱们在 server 中配置转发规则:

location /jinlu/ {
  proxy_pass http://zqq.com;
  tcp_nodelay     on;
  proxy_set_header Host            $host;
  proxy_set_header X-Real-IP       $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

这样配置完成后,假设我目前的域名是 javaboy.org,那么用户经过 http://www.javaboy.org/jinlu/** 格式的地址就能够访问到我服务端的接口。

前端部署

以 Vue 为例,若是是 SPA 应用,项目打包以后,就是一个 index.html 还有几个 js、css、images 以及 fonts ,这些都是静态文件,咱们将静态文件首先上传到服务器,而后在 nginx.conf 中配置静态资源访问,具体配置以下:

location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff|html|txt|pdf|) {
   root /usr/local/nginx/html/;#全部静态文件直接读取硬盘
   expires 30d; #缓存30天
} ​​​​

固然我这里是按照资源类型来拦截的,即后缀为 js、css、ico 等的文件,通通都不进行请求分发,直接从本地的 /usr/local/nginx/html/ 目录下读取并返回到前端(咱们须要将静态资源文件上传到 /usr/local/nginx/html/ 目录下)。

若是咱们的服务器上部署了多个项目,这种写法就不太合适,由于多个项目的前端静态文件确定要分门别类,各自放好的,这个时候咱们同样能够经过路径来拦截,配置以下:

location /jinlu-admin/ {
   root /usr/local/nginx/html/jinlu-admin/;#全部静态文件直接读取硬盘
   expires 30d; #缓存30天
} ​​​​

这样,请求路径是 /jinlu-admin/ 格式的请求,则不会进行请求分发,而是直接从本机的 /usr/local/nginx/html/jinlu-admin/ 目录下返回相关资源。采用这方方式配置静态资源,咱们就能够部署多个项目了,多个项目的部署方式和上面的同样。

这样部署完成以后,假设个人域名是 javaboy.org ,那么用户经过 http://www.javaboy.org/jinlu-admin/**
格式的请求就能够访问到前端资源了。

此时你们发现,前端的静态资源和后端的接口如今处于同一个域之中了,这样就不存在跨域问题,因此我一开始基说必用 JSONP 或者 CORS 去解决跨域。特殊状况可能须要在 nginx 中配置跨域,这个松哥之后再和你们细聊~​

好了,不知道小伙伴有没有看懂呢?有问题欢迎留言讨论。

关注公众号【江南一点雨】,专一于 Spring Boot+微服务以及先后端分离等全栈技术,按期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货!

相关文章
相关标签/搜索