問題簡介:在我發送post請求之前,瀏覽器總是會多發送一個option請求,而由于我們的Nginx服務器直接屏蔽了options請求,導致options請求失敗,進而導致后面的請求無法發送。
我們都知道請求分為同源請求和跨源請求,而我們常用的AJAX只能用于同源請求,要想跨域,我們可以使用JSONP,CORS, WebSocket來實現。本文主要來帶大家簡單了解下CORS。
CORS是跨域資源共享(Cross-origin resource sharing)的簡稱
CORS請求需要瀏覽器和服務端同時支持。
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
對于簡單請求,瀏覽器會在其請求頭部中增加一個Origin字段,
Orgin: http://example.com:10000
來說明這個請求來自哪個源(即請求來自哪里,協議+域名+端口),當服務器收到這個請求,會查看請求的origin字段,根據源來判斷是否允許該跨域請求。
若允許,則會在返回的頭部信息中加上:
Access-Control-Allow-Origin: http://example.com:10000
該字段表示該跨域請求被允許。
若不允許,也會正常返回一個HTTP Response,但是Header中不包括此字段。這時瀏覽器收到后就會知道請求失敗(即使HTTP回應的狀態碼是200)。
非簡單請求
不符合簡單請求要求的被稱為非簡單請求。
對于非簡單請求,會在真正請求之前先發送一個options請求,稱之為預請求,這就是為什么我們在開發的時候明明沒有發送過什么options類型的請求卻經常看到的原因。預請求的作用是用來詢問后面真正的請求是否被許可,預請求很簡單,有三個主要的字段:
origin: http://example.com:10000
Access-Control-Request-Method: post
Access-Control-Request-Headers: auth-token
分別表示請求的源,真正請求的方式,真正請求的額外頭信息字段(多個用逗號分開),服務器端收到預請求后,會檢查這三個字段,確認允許后會在頭部返回如下信息:
Access-Control-Allow-Origin: http://example.com:10000
Access-Control-Allow-Methods: get, post, put, delete
Access-Control-Allow-Headers: auth-token
如沒有這三個字段,則表示不允許后面真正的請求,則瀏覽器不會繼續發送真正的請求;有則表示允許,被允許后,則會像發送簡單請求那樣發送真正的請求。
參考鏈接
同源政策及其避規方法 http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
CORS詳解 http://www.ruanyifeng.com/blog/2016/04/cors.html