關於先後端分離的概念,以前我的的理解主要停留在開發模式上的分離,而實際上要真正實現先後端徹底分離還須要涉及部署環境的分離,全部此處介紹的先後端分離應該是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——跨域請求那些事兒