1. 程式人生 > >跨域問題的根本解決方案CORS

跨域問題的根本解決方案CORS

介紹

關於跨域問題有很多的解決方案,這裡我們總結一下目前最通用最強大的解決方案:CORS。

W3C 的 Web 工作組推薦了一種新的機制,即跨域資源共享(Cross-origin Resource Sharing),簡稱CORS。其實這個機制就是實現了跨站訪問控制,使得安全地進行跨站資料傳輸成為可能。

跨源資源共享標準( cross-origin sharing standard) 使得以下場景可以使用跨站 HTTP 請求:

  1. 使用 XMLHttpRequest 或 Fetch發起跨站 HTTP 請求。
  2. Web 字型 (CSS 中通過 @font-face 使用跨站字型資源),因此,網站就可以釋出 TrueType 字型資源,並只允許已授權網站進行跨站呼叫。
  3. WebGL 貼圖
  4. 使用drawImage繪製
  5. Images/video 畫面到canvas.
  6. 樣式表(使用 CSSOM)
  7. Scripts (for unmuted exceptions)

CORS分為簡單請求複雜請求,處理方法也是有不同的,所以我們分別總結。

簡單請求

什麼是簡單請求呢?同時滿足以下兩個條件,就是簡單請求:

  1. 請求是下列之一:
    HEAD
    GET
    POST
  2. 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-OriginHTTP響應報文中的一個欄位,OriginHTTP請求報文中的以一個欄位,如果不清楚這兩個欄位的話,可以自行查閱關於HTTP報文的知識,比如HTTP | MDN

複雜請求

如果不是簡單請求,那就是複雜請求,比如請求的方法是PUT或者DELETE,比如Content-Type欄位的型別是application/json,比如設定了自定義頭資訊。

複雜請求就是比簡單請求多了個預檢請求(preflight)而已。

預檢請求就是瀏覽器先詢問伺服器,當前網頁所在的域名是否在伺服器的許可名單之中,以及可以使用哪些HTTP動詞和頭資訊欄位。只有得到肯定答覆,瀏覽器才會發出正式的XMLHttpRequest請求,否則就報錯。

預檢請求用的請求方法是OPTIONS,表示這個請求是用來詢問的。頭資訊裡面,關鍵欄位是Origin,表示請求來自哪個源。除了Origin欄位,還有兩個欄位非常重要:Access-Control-Request-MethodAccess-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請求,是目前跨域問題的根本解決方案。