前言Hi,大家好,我是麦叔,今天给大家带来使用阿里云服务器部署前后端分离项目的实战。最近买了个阿里云服务器和域名,买来之后就扔在哪里放着了(想不通当时为什么买,哈哈哈)!刚好赶上
前言 Hi,大家好,我是麦叔,今天给大家带来使用阿里云服务器 部署前后端分离项目 的实战。最近买了个阿里云服务器和域名,买来之后就扔在哪里放着了(想不通当时为什么买,哈哈哈 )!刚好赶上公司新项目上线,老大让我部署前后端分离项目,就用他来搞一场演习部署吧!
阅读完本文章,你会掌握利用nginx
做代理和跨域处理,如果在两台服务器部署前后端分离项目。如果以后有需要,建议收藏,真的会少踩很多坑.
一 你需要准备? 在这里交代一下我的环境
两台阿里云ECS
服务器:服务器A部署前端项目 服务器B部署后端项目 vue 2.6.10 Spring 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- Agent, X- Requested- With, If- Modified- Since, Cache- Control, Content- Type, token'; add_header 'Access-Control-Max-Age' 1728000 ; 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 http: // localhost: 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 是否跨域 原因 http://www.test.com/ http://www.test.com/index.html 否 同源(协议、域名、端口号相同) http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https) http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu) http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog) http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)
4.2 跨域的解决方案 1 Java后端全局配置 @Configuration public 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) ; } }
@Configuration public 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: "http://localhost:8080" } , '/test2' : { target: "http://localhost: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 : "http://localhost:8080/test" , dataType : "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' 1728000;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 http://localhost: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 'http://ip地址:8081/api/login' from origin 'http://ip地址: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 'http://ip地址:8081, http://ip地址:8081' , but only one is allowed. app. 07bc0251. js: 1 Error: Network Error
可以看出使我们配置了两次跨域处理,既然我们通过nginx
统一处理跨域问题,于是我们需要注释掉后端代码中的配置
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings ( CorsRegistry registry) { registry. addMapping ( "/**" ) . allowedOrigins ( "*" ) . allowCredentials ( true ) . allowedMethods ( "GET" , "POST" , "PUT" , "DELETE" , "OPTIONS" ) . maxAge ( 3600 ) ; } }
重新部署项目以后,我们再次访问,发现正常了
到这里,文章就结束了,谢谢大家阅读