跨域問題及前後端常見解決方案?

語言: CN / TW / HK

一.什麼是跨域?

跨域其實就是瀏覽器的同源策略所導致的。protocol(協議)、domain(域名)、port(端口)三個有一個不一致,就會產生跨域。

二.跨域的示例?

瞭解跨域的概念後,解下來我們就來模擬出現跨域的狀況,我們用node來創建後端服務器,並編寫相關接口。不瞭解node的同學,可移步到我這篇文章,從0到1學習Node.js系列教程(第一篇):API接口初體驗

編寫一個post請求:

image.png

用postman調這個接口,成功調通了。

image.png

然後我們創建一個vue項目來進行聯調,就會發現請求沒有返回。

image.png

可是剛剛我們用postman來測試都是可以的呀,彆着急,我們來看看console,就會發現有以下報錯,出現以下報錯其實就是出現了跨域問題

image.png

這也充分證明了跨域是瀏覽器的行為,並不是服務器的行為,出現這樣的狀況是因為你在瀏覽器其實是發出請求了的,服務器也接收到請求,並返回了數據了。那這裏為什麼沒有接收到數據了,是因為被瀏覽器截胡了,所有導致你接收不到服務器返回的數據

三.跨域的常見解決方案?

1.在服務器端的請求頭裏面設置CROS允許跨域

CORS (Cross-Origin Resource Sharing,跨域資源共享)是一個系統,它由一系列傳輸的HTTP頭組成,這些HTTP頭決定瀏覽器是否阻止前端 JavaScript 代碼獲取跨域請求的響應。

同源安全策略 默認阻止“跨域”獲取資源。但是 CORS 給了web服務器這樣的權限,即服務器可以選擇,允許跨域請求訪問到它們的資源。

那怎麼解決呢,英文不好的同學,我們把這段報錯複製到翻譯裏面,翻譯也是我自己經常使用的一個工具。我承認我英文不好,但是有工具替我解決問題。

image.png

查看翻譯,可以明確看到提示:請求的資源上不存在'access control Allow Origin'標頭 所以這裏其實已經給出了跨域的解決方案,那就是在後端的請求頭裏面設置CROS允許跨域。(這裏要注意代碼中並沒有對get請求進行設置,這是因為get請求並不存在跨域問題,比如你在瀏覽器的地址欄是可以直接訪問的,利用ajax也是可以了,這裏我就不展示了)

image.png

注意一定要放在應用路由之前,建議位置【var app = express();】後面

再次在前端項目中請求,我們發現能正常訪問的,那麼這個跨域問題我們解決了。

image.png

2.前端利用proxy代理解決跨域(node正向代理)

前面我們講到了後端在可以在請求頭中設置CROS允許跨域,我們把剛剛在服務端設置跨域問題的代碼註釋掉,再次復現跨域問題。 \ 在實際項目中比如我們目前市場上大多數使用的都是vue或者react技術棧的項目,如果後端不給解決,或者後端忘記解決了,那我們一定要去求後端解決嗎?同樣都是工程師,為啥要去求後端解決呢?作為前端工程師我們也有自己的解決方案,那就是利用proxy進行代理解決跨,這裏vue2項目為例。

①在前端先建配置文件vue.config.js,然後配置解決跨域的代碼。

image.png

②在request.js裏面配置baseURL。

image.png

③重啟前端服務。

這一點非常重要,因為這屬於配置文件,如果你不重啟服務,是不會生效的。不然你明明改好了,卻在代碼層面糾結為啥不行?

④展示效果

代理後的請求路徑: image.png

請求參數:

image.png

請求結果:

image.png

以上就是就是跨域的常見解決方案,我這裏分別演示了前端解決方案後端解決方案,在日常的項目中,我們用得最多的其實也是這兩種方式。

而跨域的解決方案還有以下方式:

3.Nginx 反向代理

4.JSONP

5.Websocket

6.window.postMessage

7.document.domain + Iframe

8.window.location.hash + Iframe

9.window.name + Iframe

10.瀏覽器開啟跨域(終極方案)

這幾種方案,大家瞭解即可。有興趣的同學可以看看其他大佬的這篇文章哦。10種跨域解決方案(附終極大招),今天的分享就到這裏吧。

### 筆者往期好文:

微信小程序如何分包?

前端性能優化,如何提高首屏加載速度?

前端技術日新月異,vue3.0的時代已經來臨...