深入跨域

2023-11-15 12:02:30

前言

跨域這兩個字就像一塊狗皮膏藥一樣黏在每一個前端開發者身上,無論你在工作上或者面試中無可避免會遇到這個問題。如果在網上搜尋跨域問題,會出現許許多多方案,這些方案有好有壞,但是對於闡述跨域的原理和在什麼情況下需要用什麼方案,缺少系統性的說明。大家在工作中可能因為大佬們已經設定好了,不會產生跨域,但是作為一個前端的開發人員,面對跨域的問題,還是需要從原理上去理解跨域的原因,在不同的情況中,我們該如何去處理。

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.comb.baidu.com ,也是屬於不同域的,仍會出現這個問題。

那麼到底什麼是跨域,跨域既然影響了我們的開發工作,那又為什麼要有對跨域的限制呢?下面讓我們來了解一下跨域的歷史產生原因和作用吧。

2 跨域

2.1 演變史

以下內容為個人猜測,僅供參考,勿噴