当心这些“坑”!阿里云服务器部署前后端分离项目

点击上方“蓉李纪”,关注订阅更多优质内容

后台回复"加群",加入技术交流群一起进步

前言

Hi,大家好,我是麦叔,今天给大家带来使用「阿里云服务器」部署「前后端分离项目」的实战。最近买了个阿里云服务器和域名,买来之后就扔在哪里放着了(「想不通当时为什么买,哈哈哈」)!刚好赶上公司新项目上线,老大让我部署前后端分离项目,就用他来搞一场演习部署吧!

阅读完本文章,你会掌握利用nginx做代理和跨域处理,如果在两台服务器部署前后端分离项目。如果以后有需要,建议收藏,真的会少踩很多坑.

一 你需要准备?

在这里交代一下我的环境

两台阿里云ECS服务器:服务器A部署前端项目  服务器B部署后端项目vue 2.6.10Spring Boot 2.2.4.RELEASE

二 项目打包

2.1 前端项目

我们的前端项目使用vue开发,在前端项目的package.json文件中,一般都会定义用于打包的脚本

在我们开发工具的控制台输入命令npm run build:sit进行打包

当我们打包完成之后,会在我们项目目录下出现dist目录,里面存放的就是我们打包出来的文件

2.2 后端项目

我们后端项目采用spring boot+maven开发,请「注意」要在父级项目(root)下依次执行clean->install就能成功打包

打完包的文件位于target目录,xxxxx.jar文件就是我们要部署的

三 项目部署

我这里采用阿里云服务器进行部署,会将前端项目和后端项目部署到不同的服务器,通过nginx进行代理和跨域处理

服务器部署项目环境服务器A前端项目nginx服务器B后端项目nginx+jdk8

因为除了nginx以为,其他环境搭建不是我们本文重点,如果你的服务器第一次部署项目,预计还需要安装jdk mysql redis 等环境

3.1 开启ECS服务器端口

首先,登录阿里云进入云服务器ECS控制台,点击安全组---->配置规则

大家点击「手动添加」添加规则即可:大家可以仿照填写我下面那个红框配置即可

为什么需要开启端口?

因为我待会要装的nginx的监听端口需要配置为8081,阿里云服务器需要在后台开启才可以,不然nginx无法监听

3.2 Linux 下nginx的安装

服务器A和服务器B都需要安装nginx,主要用作项目代理.大家参考文末推荐阅读第一篇文章

3.3 部署前端项目

登录服务器A,新建一个文件夹,一般我是在根目录下新建data目录,在data目录按项目名区分,比如:/data/milogenius/将打包的前端项目dist目录上传即可

服务器A中nginx配置,监听端口号就是刚刚我们开启的8081

大家在使用时候,需要更改的地方为 8081 /web   alias后面的绝对路径

server {        listen       8081;        server_name  localhost;        #charset koi8-r;        #access_log  logs/access.log  main;        location /web {                        alias /data/milogenius/dist;                        index index.html;                }    }

「注意」:服务器A只需要配置前端项目代理就行,后端项目代理不需要配置,因为在前后端项目部署在不同的服务器,在前端项目请求后端接口,不走前端服务器

3.4 部署后端服务

登录服务器A,新建一个文件夹,一般我是在根目录下新建data目录,在data目录按项目名区分,比如:/data/milogenius/将打包的后端项目jar包上传即可

启动jar包,将xxxx替换为自己的名称

nohup java -jar xxxxx.jar >./xxxxxx.log 2>&1 &

服务器B中nginx的配置,监听端口号就是刚刚我们开启的8081,9888是我们后端项目启动的端口.这里我们采用nginx统一处理跨域问题

大家在使用时候,需要将端口号:8081 /api  proxy_pass都修改为自己项目的配置

server {        listen       8081;        server_name  localhost;        #charset koi8-r;        #access_log  logs/access.log  main;       location /api {                        if ($request_method = OPTIONS) {                                add_header Access-Control-Allow-Origin $http_origin;                                add_header Access-Control-Allow-Credentials true;                                add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE, OPTIONS;                                add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Age                                nt,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token;                                add_header Access-Control-Max-Age ;                                add_header Content-Type text/plain charset=UTF-8;                                add_header Content-Length 0;                                return 204;                }                        add_header Access-Control-Allow-Origin $http_origin;                        add_header Access-Control-Allow-Credentials true;                        add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE, OPTIONS;                        add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X                        -Requested-With,If-Modified-Since,Cache-Control,Content-Type,token;                        proxy_pass :9888;                        client_max_body_size 1024m;                        proxy_set_header X-Real-IP $remote_addr;                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;                        proxy_set_header Host $host;                        proxy_redirect off;                }    }

四 跨域处理

在前后端分离项目中,跨域问题是必须要解决的,在刚刚部署后端项目时候,我们已经在nginx中配置了统一的跨域解决方案,接下来我们在了解一下这一块知识

4.1 什么是跨域

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

当一个请求url的「协议、域名、端口」三者之间任意一个与当前页面url不同即为跨域

「当前页面url」「被请求页面url」「是否跨域」「原因」//index.html否同源(协议、域名、端口号相同)/https://www.test.com/index.html跨域协议不同(http/https)/http://www.baidu.com/跨域主域名不同(test/baidu)/http://blog.test.com/跨域子域名不同(www/blog):8080/:7001/跨域端口号不同(8080/7001)

4.2  跨域的解决方案

1 Java后端全局配置@Configurationpublic class GlobalCorsConfig {    @Bean    public CorsFilter corsFilter() {        CorsConfiguration config = new CorsConfiguration();          config.addAllowedOrigin("*");          config.setAllowCredentials(true);          config.addAllowedMethod("*");          config.addAllowedHeader("*");          config.addExposedHeader("*");        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();        configSource.registerCorsConfiguration("/**", config);        return new CorsFilter(configSource);    }}@Configurationpublic class MyConfiguration extends WebMvcConfigurerAdapter  {  @Override      public void addCorsMappings(CorsRegistry registry) {          registry.addMapping("/**")                  .allowCredentials(true)                  .allowedHeaders("*")                  .allowedOrigins("*")                  .allowedMethods("*");    }  }

controller方法加注解CrossOrigin,origin="*"代表所有域名都可访问

@RequestMapping("/tet")@CrossOrigin(origins = "*",maxAge = 3600)public String test( ){  return "本方法支持跨域请求!!!";}2 vue-cli项目 webpack代理解决跨域问题,在vue.config.js文件中加入如下代码// 生成代理配置对象,可配置多个代理地址let proxyObj = {    /test: {        target: ":8080"    },    /test2: {        target: ":8081"    }};module.exports = {    baseUrl: /,    outputDir: dist,    lintOnSave: false,    runtimeCompiler: true,    devServer: {        contentBase: "./",        port: 8080,        disableHostCheck: true,        proxy: proxyObj,        before: app => { }    }}3 jQuery的ajax jsonp解决跨域问题$.ajax({          type : "get",          async:false,          url : ":8080/test",          dataType : "jsonp",//数据类型为jsonp          jsonp: "jsonpCallback",//服务端返回回调方法名        success : function(data){              alert(JSON.stringify(data));        },          error:function(){              alert(请求错误!);          }      });  4 nginx全局处理

最后一种就是我们本次采用的nginx配置方式,

location /api {if ($request_method = OPTIONS) {add_header Access-Control-Allow-Origin $http_origin;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE, OPTIONS;add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token;add_header Access-Control-Max-Age ;add_header Content-Type text/plain charset=UTF-8;add_header Content-Length 0;return 204;}add_header Access-Control-Allow-Origin $http_origin;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE, OPTIONS;add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token;proxy_pass :9888;client_max_body_size 1024m;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $host;proxy_redirect off;}

四 访问项目

现在我们访问前端项目,使用地址http://服务器A外网ip:8081/web,发现报了如下错误

Access to XMLHttpRequest at 地址:8081/api/login from origin 地址:8081 has been blocked by CORS policy: Request header field tenant_code is not allowed by Access-Control-Allow-Headers in preflight response.

可以看出使我们前端项目访问后端项目,请求头中的tenant_code不被允许,所以我们需要在服务器B中的nginx中添加允许此请求头

add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token,tenant_code;

配置完以后,重启nginx,进行重新访问,发现报了如下错误

The Access-Control-Allow-Origin header contains multiple values 地址:8081, 地址:8081, but only one is allowed.app.07bc0251.js:1 Error: Network Error

可以看出使我们配置了两次跨域处理,既然我们通过nginx统一处理跨域问题,于是我们需要注释掉后端代码中的配置

@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {    @Override    public void addCorsMappings(CorsRegistry registry) {        registry.addMapping("/**")            .allowedOrigins("*")            .allowCredentials(true)            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")            .maxAge(3600);     }    }

重新部署项目以后,我们再次访问,发现正常了

到这里,文章就结束了,谢谢大家阅读

麦叔告诉你,Linux下安装nginx都踩了那些坑 2020-08-31 速看!今天我才知道,UUID还分五个版本 2020-08-23 涅槃之路暗藏「捷径」!你必须了解分布式! 2020-08-17 点个在看支持我吧,转发就更好了