跨域問題的根本解決方案CORS
介紹
關於跨域問題有很多的解決方案,這裡我們總結一下目前最通用最強大的解決方案:CORS。
W3C 的 Web 工作組推薦了一種新的機制,即跨域資源共享(Cross-origin Resource Sharing),簡稱CORS。其實這個機制就是實現了跨站訪問控制,使得安全地進行跨站資料傳輸成為可能。
跨源資源共享標準( cross-origin sharing standard) 使得以下場景可以使用跨站 HTTP 請求:
- 使用 XMLHttpRequest 或 Fetch發起跨站 HTTP 請求。
- Web 字型 (CSS 中通過 @font-face 使用跨站字型資源),因此,網站就可以釋出 TrueType 字型資源,並只允許已授權網站進行跨站呼叫。
- WebGL 貼圖
- 使用drawImage繪製
- Images/video 畫面到canvas.
- 樣式表(使用 CSSOM)
- Scripts (for unmuted exceptions)
CORS分為簡單請求和複雜請求,處理方法也是有不同的,所以我們分別總結。
簡單請求
什麼是簡單請求呢?同時滿足以下兩個條件,就是簡單請求:
- 請求是下列之一:
HEAD
GET
POST
- HTTP的頭資訊不超出以下幾種欄位:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type
:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
實現方法非常簡單,只需要把伺服器的響應報文裡的Access-Control-Allow-Origin
設定為*
或者包含由 Origin
指明的站點。
Access-Control-Allow-Origin
是HTTP響應報文中的一個欄位,Origin
是HTTP請求報文中的以一個欄位,如果不清楚這兩個欄位的話,可以自行查閱關於HTTP報文的知識,比如HTTP | MDN。
複雜請求
如果不是簡單請求,那就是複雜請求,比如請求的方法是PUT
或者DELETE
,比如Content-Type
欄位的型別是application/json,比如設定了自定義頭資訊。
複雜請求就是比簡單請求多了個預檢請求(preflight)而已。
預檢請求就是瀏覽器先詢問伺服器,當前網頁所在的域名是否在伺服器的許可名單之中,以及可以使用哪些HTTP動詞和頭資訊欄位。只有得到肯定答覆,瀏覽器才會發出正式的XMLHttpRequest請求,否則就報錯。
預檢請求用的請求方法是OPTIONS
,表示這個請求是用來詢問的。頭資訊裡面,關鍵欄位是Origin
,表示請求來自哪個源。除了Origin
欄位,還有兩個欄位非常重要:Access-Control-Request-Method
和Access-Control-Request-Headers
,分別表示允許的請求方法和請求頭。
舉一個具體的例子:
現在,我們有一個頁面向伺服器傳送了一個POST
請求,並且我們自己定義了一個請求頭欄位My-HEADER
,這時候瀏覽器就會首先發送一個OPTION
請求來做預檢請求,請求頭裡有以下欄位:
Access-Control-Request-Method: POST
Access-Control-Request-Headers: My-HEADER
如果預檢請求成功的話,響應頭裡的內容如下:
Access-Control-Allow-Origin: http://example.com //表明伺服器允許http://example.com的請求
Access-Control-Allow-Methods: POST, GET, OPTIONS //表明伺服器可以接受POST, GET和 OPTIONS的請求方法
Access-Control-Allow-Headers: My-HEADER //傳遞一個可接受的自定義請求頭列表
Access-Control-Max-Age: 3000000 //告訴瀏覽器,本次預檢請求的響應結果有效時間是多久
總結
以上就是CORS方法解決跨域問題的流程,CORS支援所有型別的HTTP請求,是目前跨域問題的根本解決方案。