CORS 需要瀏覽器和伺服器同時支援。目前,所有瀏覽器都支援該功能。
整個 CORS 通訊過程,都有瀏覽器自動完成,使用者無感知,對開發者而言,CORS 和 AJAX 通訊無異,前端程式碼完全一樣。瀏覽器如果發現 AJAX 請求跨域,會自動新增一些附加的頭資訊,如果是非簡單請求,會多出一次 OPTION 請求。實現 CORS 通訊的關鍵是伺服器。只要伺服器實現了 CORS 介面,就可以跨域通訊。
簡單請求兩大條件
請求方法屬於以下三種方式之一
- HEAD
- GET
- POST
HTTP 的頭資訊不超出以下幾種欄位
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限於三個值
application/x-www-urlencode
、multipart/form-data
、text/plain
簡而言之,簡單請求就是簡單的 HTTP 方法和簡單的 HTTP 頭資訊的結合
其實簡單請求就是傳統的表單請求,規避 CORS 的限制
簡單請求
基本流程
瀏覽器自動在頭資訊中新增一個 Origin 欄位,說明本次請求來源哪個域(協議+域名+埠),伺服器會根據這個值,決定是否同意本次請求。
如果 Origin 指定的源,不在許可範圍內,伺服器會返回一個正常的 HTTP 響應,但響應的頭資訊不包含 Access-Control-Allow-Origin
欄位
withCredentials 屬性
CORS 請求預設不包含 Cookie 資訊(以及 HTTP 認證資訊等),這是為了降低 CSRF 攻擊的風險。如果伺服器需要拿到 Cookie,這時需要伺服器顯式指定 Access-Control-Allow-Credentials
欄位,告訴瀏覽器可以傳送 Cookie
Access-Control-Allow-Credentials: true
同時,必須在 AJAX 請求中設定 withCredentials 屬性。
需要注意的式,如果伺服器要求瀏覽器傳送 Cookie,Access-Control-Allow-Origin
不能設為星號,必須指定明確的、與請求頁面一致的域名。同時,Cookie 依然遵循同源策略,只有用伺服器域名設定的Cookie 才會上傳,其他域名的 Cookie 並不會上傳,且(跨域)原頁面程式碼中的 document.cookie
也無法讀取伺服器域名下的 Cookie
非簡單請求
預檢請求
非簡單請求是對伺服器提出特殊要求的請求,比如請求方法是 PUT
或 DELETE
,或者 Content-Type
欄位的型別是 application/json
非簡單請求的 CORS 請求,會在正式通訊之前,增加一次 HTTP 查詢請求,即預檢請求。詢問當前網頁所在的域名是否在伺服器的許可名單之中,以及可以使用哪些 HTTP 方法和頭資訊欄位。只有得到肯定回覆,瀏覽器才會發出正式的 XMLHttpRequest
請求,否則報錯
本作品採用《CC 協議》,轉載必須註明作者和本文連結