關於預檢請求:
我們經常看到請求裏偶爾會帶着一個OPTIONS請求,這並不是我們人工添加的,爲什麼會出現呢? 原來在CORS跨域資源共享時,如果這次請求符合預檢請求觸發條件,就會被認爲請求有一定風險,服務器它就不敢主動幫我們接受請求了,就需要由我們指定這次跨域請求哪些安全哪些不安全,所以會比普通cors請求多一步,需要提前通過OPTIONS方法的預檢請求,和服務器確認我們的請求符合不符合條件:
大概看下,OPTIONS預檢請求裏就這幾個請求頭和響應頭:
請求頭:
- Origin:當前請求源,和響應頭裏的
Access-Control-Allow-Origin
對標, 是否允許當前源訪問,Origin是不可修改的 - Access-Control-Request-Headers:本次真實請求的額外請求頭,和響應頭裏的
Access-Control-Allow-Headers
對標,是否允許真實請求的請求頭 - Access-Control-Request-Method:本次真實請求的額外方法,和響應頭裏的
Access-Control-Allow-Methods
對標,是否允許真實請求使用的請求方法
響應頭
Access-Control-Allow-Credentials
:
這裏的Credentials(憑證)其意包括:Cookie ,授權標頭或 TLS 客戶端證書,默認CORS請求是不帶Cookies的,這與JSONP不同,JSONP每次請求都攜帶Cookies的,當然跨域允許帶Cookies會導致CSRF漏洞。如果非要跨域傳遞Cookies,web端需要給ajax設置withCredentials
爲true,同時,服務器也必須使用Access-Control-Allow-Credentials
頭響應。此響應頭true意味着服務器允許cookies(或其他用戶憑據)包含在跨域請求中。另外,簡單的GET請求是不預檢的,即使請求的時候設置widthCrenditials
爲true
,如果響應頭不帶Access-Control-Allow-Credentials
,則會導致整個響應資源被瀏覽器忽略。Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Origin
Access-Control-Expose-Headers
:
在CORS中,默認的,只允許客戶端讀取下面六個響應頭(在axios響應對象的headers裏能看到):
如果這六個以外的響應頭要是想讓客戶端讀取到,就需要設置Cache-Control Content-Language Content-Type Expires Last-Modified Pragma
Access-Control-Expose-Headers
這個爲響應頭名了,比如Access-Control-Expose-Headers: Token
Access-Control-Max-Age
:設置預檢請求的有效時長,就是服務器允許的請求方法和請求頭做個緩存。
關於預檢請求觸發特性我的一些測試:
- 兩個一模一樣的CORS請求,兩個都會先發送OPTIONS預檢請求:
- 即使設置了
Access-Control-Max-Age
,並且在時間範圍內服務器修改CORS響應頭,瀏覽器也會按照新的CORS響應頭處理請求
預檢請求的觸發條件:
- 不是
GET
、HEAD
、POST
其中之一; - 下面所列請求頭以外的請求頭(額外請求頭):
Accept Accept-Language Content-Language Content-Type (需要注意額外的限制,下一個觸發條件) DPR Downlink Save-Data Viewport-Width Width
- Content-Type不是下面這三個:
text/plain multipart/form-data application/x-www-form-urlencoded