跨域這兩個字就像一塊狗皮膏藥一樣黏在每一個前端開發者身上,無論你在工作上或者面試中無可避免會遇到這個問題。如果在網上搜索跨域問題,會出現許許多多方案,這些方案有好有壞,但是對於闡述跨域的原理和在什麼情況下需要用什麼方案,缺少系統性的說明。大家在工作中可能因為大佬們已經配置好了,不會產生跨域,但是作為... ...
前言
跨域這兩個字就像一塊狗皮膏藥一樣黏在每一個前端開發者身上,無論你在工作上或者面試中無可避免會遇到這個問題。如果在網上搜索跨域問題,會出現許許多多方案,這些方案有好有壞,但是對於闡述跨域的原理和在什麼情況下需要用什麼方案,缺少系統性的說明。大家在工作中可能因為大佬們已經配置好了,不會產生跨域,但是作為一個前端的開發人員,面對跨域的問題,還是需要從原理上去理解跨域的原因,在不同的情況中,我們該如何去處理。
1 業務場景
1.1 介紹
WMS6.0是一款專門為倉儲業務打造的合作開發平臺,前臺BP可以獨立開發或者定製現有的流程,接入到WMS6.0中,實現自定義業務,使前臺BP只需要關註自己的業務,不用專註其他功能,提升前臺BP的開發效率。。
作為一個合作平臺,WMS6.0 PC端支持獨立頁面擴展和頁面內部功能擴展,支持前臺BP可以進行獨立部署,實現最大程度的解耦。接入方案如下:
- 獨立頁面擴展,以完全獨立業務模塊的方式接入。針對部分合作方需要自己完全獨立開發頁面的情況,WMS6.0提供了微前端的框架進行接入。
- 頁面內部功能擴展,以預留插槽的方式接入。如圖1中標註部分所示,整體頁面被劃分為多個區域,其中包含了通用的數據模塊 + bp接入模塊。當合作方有個性化的數據統計需求時,可以進行獨立開發,然後接入現有公用頁面中。
在bp接入平臺的過程中,我們遇到了各種各樣的問題,如前後端如何聯調、如何在不衝突的情況下自定義全局屬性、如何部署上線等等,下麵我們主要就前後端聯調中遇到的跨域問題進行討論。
在使用上述預留插槽的接入方式時,為了通用模塊與接入模塊之間的數據同步等方便進行,WMS6.0中並沒有使用老式的iframe,而是採用了vue註冊的方式,實現在同一個頁面中載入。因此合作方在獨立模塊中發起的服務端請求,其來源其實仍是當前通用頁面。
而WMS6.0並不能確保所有的合作方服務端均在同一個功能變數名稱下,由此也就產生了各種交互問題。
1.2 wms6.0請求鏈路
我們先來看一下WMS6.0現有的通用網路請求整體鏈路。
當用戶觸發了網路請求,會通過基站或者倉庫的路由發出,然後通過網路到達物流網關,物流網關把請求轉發到Nginx,Nginx會把請求分發到具體的伺服器上進行數據處理。
下麵我們就抽取一個WMS6.0通過物流網關訪問的請求,作為實例來看一下。
通過response Headers(相應頭)我們可以看到,公司現有的物流網關會對指定功能變數名稱的頁面進行CORS跨域處理。通過Access-Control-Allow-Origin: http://a..com,我們可以知道物流網關可以接受來自指定域 http://a..com 的跨域資源請求,不會產生跨域報錯。
但是咱們部分bp合作方的介面並不是通過物流網關的,這就需要我們自己對此類介面進行跨域處理了。假如沒有進行跨域處理,那麼就會報下麵的錯了。
1.3 跨域的產生
- Access to XMLHttpRequest at '' from origin '' has been blocked by CORS policy
- Response to preflight request doesn't pass access control check
- No 'Access-Control-Allow-Origin' header is present on the requested resource.
報錯解析:
從源“本地路徑”訪問 “目標路徑(請求鏈接)”的文本傳輸請求已被CORS策略阻塞:對預檢請求的響應未通過訪問控制檢查。請求的資源上不存在'Access- control - allow - origin '報頭。
錯誤原因:
本地路徑和目標路徑不在同一個功能變數名稱下引起的跨域問題。
同時需要註意的是,就算兩個功能變數名稱是同一個二級功能變數名稱、不同三級功能變數名稱的時候,例如 a.baidu.com 和 b.baidu.com ,也是屬於不同域的,仍會出現這個問題。
那麼到底什麼是跨域,跨域既然影響了我們的開發工作,那又為什麼要有對跨域的限制呢?下麵讓我們來瞭解一下跨域的歷史產生原因和作用吧。
2 跨域
2.1 演變史
以下內容為個人猜測,僅供參考,勿噴