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

来自公众号:江南一点雨

前后端分离这个问题其实松哥和大家聊过很多了,上周松哥把自己的两个开源项目部署在服务器上以帮助大家可以快速在线预览(喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了),然后群里就有小伙伴想让松哥来聊聊如何结合 Nginx 来部署前后端分离项目?今天我们就来聊一聊这个话题。

不得不说的跨域

很多人对前后端分离部署感到困惑,其实主要是困惑跨域问题怎么解决。因为前后端分离项目在开发的时候,前端通过 nodejs 来运行,需要一个单独的端口,后端通过 Tomcat 或者 Jetty 来运行,也需要端口,两个不同的端口,就造成了跨域。

但是松哥之前多次和大家聊过这个问题,这种跨域并不是我们传统开发中真正的跨域,这个所谓的跨域只在开发环境中存在,生产环境下就不存在这个跨域问题了。所以我们不能按照以往的通过 JSONP 或者 CORS 之类的手段来解决这个跨域问题。

前后端分离开发中,前端为了能够模拟出测试数据,并且模拟出请求,一般需要借助于 nodejs 来运行,这是开发时候的状态,开发时候的配置大家可以参考这篇文章:

等开发完成后,我们会对前端项目编译打包,编译打包完成之后,就只剩下一堆 js、css 以及 html 文件了,我们把这些编译打包后的文件拷贝到后端项目中,这样再去运行就不存在跨域问题了(例如将编译打包后的静态文件拷贝到 Spring Boot 项目的 src/main/resources/static 目录下)。这种方式我就不再多说了,相信大家都会,今天咱们主要来看看如何结合 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 中配置跨域,这个松哥以后再和大家细聊~

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • 关键字:170903、周日、淘淘百天之第100天、上海 淘淘百天了,胖成球了;平时挺活泼,今天竟然出乎意料地睡了一...
    二石兄阅读 198评论 0 0
  • 2018是个告别的年份。 樱桃小丸子,海绵宝宝。童年没了。 金庸,中学时代的故事没了。 霍金,科学幻想也没了。 二...
    子非鱼lily阅读 176评论 0 3