1. 程式人生 > 其它 >前端開發過程跨域問題處理

前端開發過程跨域問題處理

作者:Duang

來源:恆生LIGHT雲社群

同域策略是什麼

同源策略是一個重要的安全策略,它用於限制一個origin的文件或者它載入的指令碼如何能與另一個origin的資源進行互動。它是一個約定,也是瀏覽器核心也最基本的安全功能,它能幫助阻隔惡意文件,減少可能被攻擊的媒介,提高安全性。同源策略會阻止一個域的javaScript指令碼和另外一個域的內容進行互動。所謂同源(即指在同一個域)就是兩個頁面具有相同的協議(protocol),主機(host)和埠號(port)。

跨域是什麼

當一個請求url的協議、域名、埠三者之間任意一個與當前頁面url不同(不在一個源)就是跨域,就會有跨域問題。

跨域問題描述

前端開發階段常會遇到跨域問題,主要原因是前後端分離導致的不在一個源,後端服務會存放在其他的伺服器上而不是開發者的本地。如在開發過程中,本地開啟一個頁面url為http://127.0.0.1/index.html,訪問介面為https://wj.hs.net/manageconsole-deploy/getCheckCode.json,這個時候介面與頁面的協議、域名、埠不同,就觸發了跨域問題。

跨域報錯,如下圖:

判斷跨域另一種方式:Option

  • 響應頭

在正式跨域的複雜請求前,瀏覽器會根據需要,自動發起一個“PreFlight”(也就是Option請求,用來讓服務端返回允許的方法(如get、post),被跨域訪問的Origin(來源,或者域),還有是否需要Credentials(認證資訊)。當在響應頭中看到跨域屬性就可判斷介面跨域。服務端返回跨域響應頭包含如下引數:

  1. Access-Control-Allow-Credentials: true

該項標誌著請求當中是否包含cookies資訊,只有一個可選值:true(必為小寫)。如果

不包含cookies,請略去該項,而不是填寫false。

  1. Access-Control-Allow-Headers: X-Requested-With,Content-Type,Authorization

用於preflight request (預檢請求)中,列出了將會在正式請求的Access-Control-Request-Headers欄位中出現的首部資訊。可支援的請求首部名字。請求頭會列出所有支援的首部列表,用逗號隔開。

  1. Access-Control-Allow-Methods: OPTION,POST,GET,DELETE

在對 preflight request.(預檢請求)的應答中明確了客戶端所要訪問的資源允許使用的方法或方法列表。

  1. Access-Control-Allow-Origin: http://127.0.0.2:3000 

允許跨域的域名,只能填萬用字元或者單域名

  1. Access-Control-Max-Age

用來指定本次預檢請求的有效期(options),單位為秒,,在此期間不用發出另一條預檢

請求

解決方案

主要解決方案思路:通過本地代理服務,代理遠端介面。

  1. 把存在跨域問題的介面寫成呼叫本地域的介面,如當前開啟頁面為[http://127.0.0.1/index.html](http://127.0.0.1/index.html),將介面請求寫為[ http://127.0.0.1/api/getCheckCode.json](http://172.27.26.243:13380/api/getCheckCode.json)
  2. 將介面轉發到後端伺服器地址。將1中的[ http://127.0.0.1/api/getCheckCode.json](http://172.27.26.243:13380/api/getCheckCode.json)轉發為https://wj.hs.net/manageconsole-deploy/getCheckCode.json

以下提供2個解決方案:

Nginx代理

Nginx介紹

Nginx是一個高效能的HTTP和反向代理web伺服器,同時也提供了IMAP/POP3/SMTP服務。我們處理跨域問題使用了nginx的http代理功能。

Nginx跨域代理操作

  1. 找到nginx.conf檔案:一般nginx.conf檔案在nginx安裝目錄下的\conf\nginx.conf檔案下;
  2. 在nginx.conf檔案新增配置:

配置介紹:

1) ``` 監聽80埠,將http://localhost的所有請求服務轉發到http://127.0.0.1:81,實際訪問頁面http://127.0.0.1:81,開啟頁面的url為http://localhost

2) ```
將http://localhost:80/api/user介面請求轉發到[https://wj.hs.net/manageconsole-deploy](https://wj.hs.net/manageconsole-deploy)/user;

Webpack代理

Webpack介紹

Webpack是一個用於現代javaScript應用程式的靜態模組打包器,和前端資源構建工具。在解決前端開發階段的跨域問題,我們使用了webpack-dev-server的proxy屬性。Webpack-dev-server是webpack官方提供的一個小型Express伺服器。使用它可以為webpack打包生成的資原始檔提供web服務,供開發除錯使用。主要提供功能:為靜態檔案提供服務、自動重新整理和熱替換(HMR)。

Webpack-dev-server中的proxy提供了代理服務。

Webpack跨域代理操作

配置介紹:

1) ``` target :表示/api/XXX會被代理到https://wj.hs.net/manageconsole-deploy/api/xxx',如:/api/user----> https://wj.hs.net/manageconsole-deploy/api/getCheckCode.json

2) ```
處理跨域設定changeOrigin: true;

3) ``` pathRewrite:不想始終傳遞/api,則需要重寫路徑,如上請求/api/getCheckCode.json會被代理到https://wj.hs.net/manageconsole-deploy/api/getCheckCode.json


## 實際開發遇到的chrome瀏覽器跨域問題

很多近期更新了chrome版本的同學會發現,本來可以訪問的頁面,在更新後頁面刷不出來了,一般原因是在Chrome 80及以上版本中,Chrome會將沒有宣告SameSite值的cookie預設設定為SameSite=Lax,在跨域請求的情況下不允許跨域攜帶cookie給後端,導致所有跨域場景下使用cookie進行鑑權的服務會受到影響。

![](file:///C:/Users/WANGSZ~1/AppData/Local/Temp/msohtmlclip1/01/clip_image010.jpg)![F0926F~1.PNG](https://developer.hs.net/storage/attachments/2021/06/22/Jau0UlPuHBGT0SYhSXMWiFe7VN84p74U3pHR1BBA.PNG "1645")

解決:

1. ```
在chrome瀏覽器位址列輸入chrome://flags並回車;
  1. 在搜尋欄中輸入SameSite by default cookies搜尋,並禁用如圖中的兩項設定,改為Disabled即可;

  2. 點選右下鍵ReLaunch重啟瀏覽器即可。

總結

前端開發除錯階段遇到的跨域問題,主要是由於前後端服務不在同一個origin導致的,可以使用代理的方式解決。

以上提供了兩種代理的方法:

·nginx高效能的HTTP代理服務

·webpack的webpack-dev-server外掛中的proxy

排除以上同源策略導致的跨域問題,介面無報錯,頁面顯示不正常情況,可以考慮是因為高版本chrome對跨域做了更多的限制導致的,可以設定chrome://flags的SameSite。

跨域問題在前端開發階段常會遇到,設定代理能夠快速解決跨域問題,並不需要後端協助,節省了除錯時間,提高開發效率。希望以上內容能夠幫助到前端開發的同學們。