跨域資源共享
CORS跨域資源共享: 允許瀏覽器向跨源服務(wù)器發(fā)出 XMLHttpRequest請(qǐng)求, 克服ajax只能同源使用的限制;
CORS需要瀏覽器和服務(wù)器同時(shí)支持; 目前所有瀏覽器都支持該功能, IE不能低于IE10;
瀏覽器一旦發(fā)現(xiàn)AJAX請(qǐng)求跨源,就會(huì)自動(dòng)添加一些附加的頭信息,有時(shí)還會(huì)多出一次附加的請(qǐng)求,但用戶不會(huì)有感覺(jué)。
實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器,要服務(wù)器實(shí)現(xiàn)了CORS接口,就可以跨源通信
瀏覽器將CORS請(qǐng)求分為2類:簡(jiǎn)單請(qǐng)求(simple request)和非簡(jiǎn)單請(qǐng)求(not-so-simple request);
簡(jiǎn)單請(qǐng)求
(1) 請(qǐng)求方法是以下三種方法之一:
HEAD
GET
POST
(2)HTTP的頭信息不超出以下幾種字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三個(gè)值application/x-www-form-urlencoded、multipart/form-data、text/plain
基本流程:
瀏覽器直接發(fā)送CORS請(qǐng)求(在頭部字段中添加 Origin字段, 標(biāo)明請(qǐng)求來(lái)自于哪個(gè)域);
服務(wù)器收到響應(yīng)后如果Origin指定的源不在許可范圍內(nèi),服務(wù)器返回一個(gè)正常的HTTP響應(yīng),瀏覽器發(fā)現(xiàn)響應(yīng)頭沒(méi)有Access-Control-Allow-Origin, 知道出錯(cuò)了,拋出一個(gè)錯(cuò)誤, 該錯(cuò)誤無(wú)法通過(guò)狀態(tài)碼識(shí)別, 因?yàn)槭且粋€(gè)正常的響應(yīng); 如果在許可范圍內(nèi),服務(wù)器的響應(yīng)結(jié)果就會(huì)多出如幾個(gè)字段:
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
Access-Control-Allow-Credentials: 表示是否允許發(fā)送Cookie;默認(rèn)情況下,Cookie不包括在CORS請(qǐng)求之中,請(qǐng)求沒(méi)有該字段;這個(gè)值也能設(shè)為true
如果要把Cookie發(fā)到服務(wù)器,一方面要服務(wù)器同意,設(shè)置如上字段值為true; 另一方面,開(kāi)發(fā)者必須在AJAX請(qǐng)求中打開(kāi)withCredentials屬性 , 開(kāi)發(fā)者必須在AJAX請(qǐng)求中打開(kāi)withCredentials屬性;
需要注意的是,如果要發(fā)送Cookie,Access-Control-Allow-Origin就不能設(shè)為星號(hào),必須指定明確的、與請(qǐng)求網(wǎng)頁(yè)一致的域名。
同時(shí),Cookie依然遵循同源政策,只有用服務(wù)器域名設(shè)置的Cookie才會(huì)上傳,其他域名的Cookie并不會(huì)上傳,且(跨源)原網(wǎng)頁(yè)代碼中的document.cookie也無(wú)法讀取服務(wù)器域名下的Cookie。
Access-Control-Expose-Headers:CORS請(qǐng)求時(shí),XMLHttpRequest對(duì)象的getResponseHeader()方法只能拿到6個(gè)基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必須在Access-Control-Expose-Headers里面指定;
非簡(jiǎn)單請(qǐng)求
不屬于簡(jiǎn)單請(qǐng)求的,都是非簡(jiǎn)單請(qǐng)求;比如請(qǐng)求方法是PUT或DELETE,或者Content-Type字段的類型是application/json。
非簡(jiǎn)單請(qǐng)求的CORS請(qǐng)求,會(huì)在正式通信之前,增加一次HTTP查詢請(qǐng)求,稱為"預(yù)檢"請(qǐng)求(preflight)。
瀏覽器先詢問(wèn)服務(wù)器,當(dāng)前網(wǎng)頁(yè)所在的域名是否在服務(wù)器的許可名單之中,以及可以使用哪些HTTP動(dòng)詞和頭信息字段。只有得到肯定答復(fù),瀏覽器才會(huì)發(fā)出正式的XMLHttpRequest請(qǐng)求,否則就報(bào)錯(cuò)。