关于先后端分离的概念,以前我的的理解主要停留在开发模式上的分离,而实际上要真正实现先后端彻底分离还须要涉及部署环境的分离,全部此处介绍的先后端分离应该是web应用的一种架构模式。html
如图,在传统架构模式中,先后端代码存放于同一个代码库中,甚至是同一工程目录下。页面中还夹杂着后端代码。先后端工程师进行开发时,都必须把整个项目导入到开发工具中(当前咱们微信提现的项目就是属于此类)。前端
而先后端分离模式在代码组织形式上有如下两种:ios
半分离:先后端共用一个代码库,可是代码分别存放在两个工程中。后端不关心或不多关心前端元素的输出状况,前端不能独立进行开发和测试,项目中缺少先后端 交互的测试用例。web
分离 :先后端代码库分离,前端代码中有能够进行Mock测试(经过构造虚拟测试对象以简化测试环境的方法)的伪后端,能支持前端的独立开发和测试。然后端代码中除了功能实现外,还有着详细的测试用例,以保证API的可用性,下降集成风险。axios
以这次喵盟项目从 先后端半分离 到 先后端分离 改造的实践为例,作如下要点总结。后端
因为以前先后端代码放在同一代码库中,前端请求服务的url直接取自当前路径便可。但分离以后,前端请求须要进行跨域请求,根据不一样的域名发送对应的url。跨域
当前喵盟域名配置以下:浏览器
'm.dm.com': {安全
baseUrl: 'http://meng.dm.com/',服务器
domain: '.dm.com'
},
'testm.youximao.cn': {
baseUrl: 'http://testmeng.youximao.cn/',
domain: '.youximao.cn'
},
'testm2.youximao.cn': {
baseUrl: 'http://testmeng2.youximao.cn/',
domain: '.youximao.cn'
},
'm-pre.youximao.tv': {
baseUrl: 'http://meng-pre.youximao.tv/',
domain: '.youximao.tv'
},
'm.youximao.tv': {
baseUrl: 'https://meng.youximao.tv/',
domain: '.youximao.tv'
}
完成第一步以后,当页面在 m.dm.com 中去请求 meng.dm.com 的时候,咱们会不出意料的被浏览器的同源策略所阻止,因此此时咱们经过CORS这位大佬来完美规避同源策略(JSNOP那位大佬只支持GET请求,故弃之)。
CORS是什么鬼?
当两个域具备相同的协议(如http), 相同的端口(如80),相同的host(如m.youximao.tv),那么咱们就能够认为它们是相同的域(协议,域名,端口都必须相同)。跨域就指着协议,域名,端口不一致,出于安全考虑,跨域的资源之间是没法交互的。
CORS(Cross-Origin Resource Sharing, 跨源资源共享)是W3C出的一个标准,其思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,仍是应该失败。所以,要想实现CORS进行跨域,须要服务器进行一些设置,同时前端也须要作一些配置和分析。
好了,接下来该是咱们前端要作的一些事情:
好像也就html中加一句话。。。
<!-- 容许跨域请求 start-->
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<!-- 容许跨域请求 end-->
若是前端模拟后端响应的话,可在对应的res中作以下配置:
// DEFAULT ALLOW CORS
res.setHeader('Access-Control-Allow-Origin', '*') // 容许跨域访问的域名
res.setHeader('Access-Control-Allow-Methods', '*') // 容许跨域请求的方法
完成第二步以后,咱们会发现登陆请求的确OK了,可是登陆以后就懵逼了,页面显示异常,查看缘由以后发现浏览器本地的cookie的确有了,可是后端服务并无获取到!
默认状况下,跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证实等)。经过将withCredentials属性设置为true,能够指定某个请求应该发送凭据。
前端关键代码:
如图,在请求上加个 withCredentials: true 便可。
固然,这只是前端打开一个开口而已,后端作的事情可就多了。
如图,后端服务在进行跨域处理的时候,须要将 Access-Control-Allow-Credentials 设为 true 便可。
原理:
以上先后端设置的ture属性(withCredentials、Access-Control-Allow-Credentials),都是容许跨域发送cookie的一个开关设置,须要先后端都作到打开模式。
踩过的坑:
在以上axios公用请求方法中配置好以后,也会有些不调用公用请求function的漏网之鱼,咱们也须要对其及时加上相应的容许传cookie配置!
<el-upload name="file" :with-credentials="true" :action="baseUrl + 'web/common/upload' + suffix" :show-file-list="false" :on-progress="progressIdCard1" :on-success="uploadIdCard1" :before-upload="beforeIdCard1">
上传
</el-upload>
以上代码为当前项目中的上传组件,该请求是自动触发的,须要添加 :with-credentials="true" 来支持cookie跨域传递
经过此次项目先后端彻底分离的改造,提高了本身对项目部署的认知,以及对请求头(request headers)和响应头(response headers)各参数有了更深入的接触和理解。
(ps: 先后端分离以后最爽就是index.html又回到本身的手上了,哈哈哈,要想偷懒加个cdn资源能够直接往html头部引入便可。)
参考资料:CORS——跨域请求那些事儿