目录
- 什么是前后端分离
- 如何在项目中体现
- 跨域问题
一、前后端分离概念
- 前提:传统web应用项目前后端都是在同一个项目中,前后端人员都会在同一个文件夹中进行编写,容易搞混。也同时随着业务的不断增加和变得复杂,代码量也越来越多。那么前后端开发的进度就很难保持一致。会出现前端页面写好,但后端接口没开发完毕,这样前端就只能等待后端开发完成,很不合理。
1.1 为什么需要前后端分离
-
前后端分离之前
-
前后端分离之后
1.2 前后端分离概念
- 前后端分离是将一个完整的web应用拆分为前端部分和后端部分的过程。其中两个部分由对应的团队来完成,各自可以是一个独立的子项目,我们称为钱前端项目和后端项目,两者之间可以利用http协议完成数据交互,从而实现跟传统web应用一样的用户效果。
- 其中前端部分和后端部分都是互相独立开发和测试的,后续需要数据交互只需前端将发送请求的地址切换为真实服务器地址即可。
二、项目中实现前后端分离
2.1 大概过程
- 1.需要将项目拆分为两个子项目。
- 2.各自搭建自己的服务器
- 3.利用各自服务器完成数据的交互(需要跨域支持)
2.3 详细过程(以express项目为例)
- 原有的express项目直接作为后端项目来继续开发。把public里的所有代码抽离出来,作为新前端项目的源代码
- 前端项目使用webpack进行打包,并可以直接将webpack的devServer作为web前端的服务器,后端服务器还是之前的
npm run start
- 3.前端配置服务器代理(跨域解决方案),实现跟后端服务器的数据交互。
三、跨域问题
- 前提:将前后端进行分离之后,就无法进行数据交互-就是因为跨域问题导致的
3.1 同源策略
-
当初在浏览器设计跟服务器进行交互时,为了保证服务器的数据安全,设置了同源策略。同源策略是指只能跟服务器同源的请求地址才能访问服务器的资源。同源策略只针对浏览器和服务器之间的交互。
-
同源
-
是指请求地址中的
端口号、协议、主机名称
必须是跟服务器完全一样,才算请求地址跟服务器是同源的语法:协议://主机名称:端口号
-
-
举例:比如服务器的地址是
http://localhost:3000
同源:http://localhost:3000/movies/addhttp://localhost:3000/html/index.html不同源:https://localhost:3000 协议不一样http://baidu.com:3000 主机不一样http://localhost:3001 端口号不一样
3.2 为什么要解决同源策略的影响
- 前后端分离之后,前端项目和后端项目的端口号就是不一样,就不符合同源策略,也就是两者之间不能进行数据交互。
3.3 跨域处理(绕过同源策略)
-
目前一共有三种方式解决跨域问题
- jsonp(了解)
- cors(理解)
- 服务器代理(推荐,熟练)
-
jsonp
-
原理:利用了
<script>
标签不受同源策略影响,利用Script标签的src作为请求地址,服务器接受后就返回一个函数的调用表达式给前端,前端直接调用该函数,服务器返回的数据就作为该函数的实际参数,从而实现了跨域数据交互处理 -
大概代码
<script>function sendMovies(data){} </script><script src="http://localhost:3000/movies/findAll"></script>后端:router.get("/findAll",function(req,res){ let movies = await ....; res.send(`sendMovies(${movies})`);})
-
缺点
- 不安全
- 支持get请求
-
-
cors(跨域资源共享-cross origin resource sharing)
-
原理:需要再服务器设置响应头的配置项
Access-Control-Allow-Origin
,值为需要跨域的请求地址。这样就可以进行跨域处理,浏览器无需任何操作。 -
代码:针对express项目,放在app.js就可以使用
var allowCrossDomain = function (req, res, next) { // 设置允许哪一个源(域)可以进行跨域访问,* 表示所有源 res.header("Access-Control-Allow-Origin", "http://localhost:8888"); //res.header("Access-Control-Allow-Origin", "*");//任何域名都可以跨域 // 设置允许跨域访问的请求头 res.header("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept,Authorization"); // 设置允许跨域访问的请求类型 res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE"); // 设置允许 cookie 发送到服务器 res.header('Access-Control-Allow-Credentials', 'true'); next();};//运用到项目中app.use(allowCrossDomain);
- 这段代码放在
var app = express()
之后即可
- 这段代码放在
-
-
服务器代理
-
原理:利用同源策略只针对
浏览器和服务器
之间,那么我们可以在浏览器和服务器新建一个中间服务器-称为代理服务器
,代理服务器需要跟浏览器页面同源,之后浏览器就向代理服务器发请求,代理服务器就向目标服务器发送请求(服务器和服务器之间,就不受影响),目标服务器处理之后就返回数据给代理服务器,而代理服务器则转发给浏览器。 -
实现
- webpack的devServer提供了代理的支持,所以只需要简单配置一下就可以实现服务器代理,从而实现浏览器和目标服务器之间的数据交互(Ajax).需要修改devServer的配置代码
module.exports = { //.... devServer:{ port:8888, open:"./index.html", proxy:{ //针对带有不同请求前缀的请求可以实现代理到不同的目标服务器。 "/api":{ target:'http://localhost:3000', pathRewrite:{ //把/api去掉,因为目标服务器不需要/api "/api":"" } }, //代理到其他服务器,没有就删掉 "/auth":{ target:"http://localhost:3004", pathRewrite:{ //去掉前缀 "/auth":"" } } } }}
-