CORS(跨域資源共享)

引用自阮一峯的網絡日誌:http://www.ruanyifeng.com/blog/2016/04/cors.html 侵刪html

1、瀏覽器將CORS請求(經過ajax方式)分紅兩類:web

1.簡單請求:須要同時知足如下兩大條件ajax

   1).請求方法爲:HEAD、GET、POST之一json

   2).HTTP的請求頭信息不超出如下字段:Accept、Accept-Language、Content-Language、Last-Event-ID、api

Content-Type:只限於三個值 application/x-www-form-urlencoded、multipart/form-data、text/plain跨域

2.非簡單請求:凡是不一樣時知足上面兩個條件的都屬於非簡單請求瀏覽器

 

2、簡單請求服務器

  瀏覽器直接發出CORS請求,在頭信息中添加一個Origin字段:cookie

// 該站點發送的ajax請求網絡

GET /x/web-interface/online HTTP/1.1
Host: api.bilibili.com
Connection: keep-alive
Accept: */* Origin: https://bangumi.bilibili.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Referer: https://bangumi.bilibili.com/anime/5978/play
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.8

經過Origin字段說明本次請求來自哪一個源,服務器根據這個值,決定是否贊成此次請求

// 正常的響應頭

HTTP/1.1 200 OK
Date: Thu, 07 Dec 2017 14:33:56 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 269
Connection: keep-alive
Access-Control-Allow-Origin: https://bangumi.bilibili.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Origin,No-Cache,X-Requested-With,If-Modified-Since,Pragma,Last-Modified,Cache-Control,Expires,Content-Type,Access-Control-Allow-Credentials
X-Cache: BYPASS from cn-sccd2-cmcc-w-02.hdslb.com
響應頭中與CORS請求相關字段
Access-Control-Allow-Origin: 必須的字段;要求值是請求的Origin的值;或者爲*,表示可任意跨域
Access-Control-Allow-Credentials:可選的字段;布爾值(默認無該字段);表示是否容許發送cookie,默認狀況下cookie不包括在CORS請求中;
若設置爲true表示服務器明確許可,cookie能夠包含在請求中一同發送給服務器
Access-Control-Allow-Headers
Access-Control-Expose-Headers:可選字段;CORS請求時,XHR對象的getResponseHeader() 方法只能拿到6個基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma;
若是想要拿到其餘字段,就須要在這個字段中指定

 

若是Origin指定的源不在許可範圍,服務器也會返回一個正常的HTTP迴應,可是瀏覽器會發現響應頭中沒有包含

指定字段: Access-Control-Allow-Origin字段,或者與請求頭中的Origin不匹配,就會知道出錯了

// 經過本地服務器向 發送http://www.bilibili.com/x/web-interface/online ajax請求的請求頭

Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive
Host:api.bilibili.com
Origin:http://127.0.0.1:7824
Referer:http://127.0.0.1:7824/hello.html
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36

 

// 經過本地文件 發送http://www.bilibili.com/x/web-interface/online ajax請求的請求頭

Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive
Host:api.bilibili.com
Origin:null
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36

//服務器能夠進行響應; 可是由於請求頭的Origin和響應頭Access-Control-Allow-Origin: https://bangumi.bilibili.com(或響應頭無該字段) 不相符,瀏覽會進行報錯;不會處理結果

HTTP/1.1 200 OK
Date: Thu, 07 Dec 2017 15:19:21 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 269
Connection: keep-alive
X-Cache: BYPASS from cn-sccd2-cmcc-w-01.hdslb.com

 

3、非簡單請求

非簡單請求是一種 對服務器有特殊要求的請求;好比說PUT或DELETE等請求,或者Content-Type字段類型爲application/json

非簡單請求會在正是通訊以前,增長一次HTTP查詢請求(預檢preflight)

詢問服務器當前域名是否在服務器許可名單當中,以及可使用的哪些HTTP動詞和字段;只有獲得確定答覆,瀏覽器纔會正是的發出ajax請求,不然報錯;

// put 請求

    var url = 'http://api.alice.com/cors';
    var xhr = new XMLHttpRequest();
    xhr.open('PUT', url, true);
    xhr.setRequestHeader('X-Custom-Header', 'value'); // 自定義頭
    xhr.send();

預檢請求頭

OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

預檢請求的方法是 OPTIONS;表示這個請求是用來詢問的,頭信息中關鍵字Origin表示來源

請求頭字段

1.Access-Control-Request-Method:表示CORS請求會用到哪些HTTP方法

2.Access-Control-Request-Headers:指定瀏覽器CORS請求會發送的頭信息字段

預檢響應

服務器確認容許跨域請求時,就能夠作出迴應

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

若是瀏覽器否認預檢請求,會返回一個正常的HTTP迴應,可是沒有任何CORS相關的頭信息字段,瀏覽器會認定瀏覽器不太贊成預檢請求,會觸發一個錯誤

響應頭字段

1.Access-Control-Allow-Methods:必須字段;逗號分隔字符串;代表服務器支持的全部跨域請求的方法;避免屢次預檢請求

2.Access-Control-Allow-Headers:若是請求中包含Access-Control-Request-Headers字段,該字段爲必須字段

3.Access-Control-Allow-Credentials:同簡單請求

4.Access-Control-Max-Age:可選字段;指定預檢有效期

 經過預檢請求後,之後每次瀏覽器的CORS請求就和簡單請求同樣會有一個Origin頭信息字段

 //本地非簡單請求

 

 

// 本地服務器非簡單請求結果

 

 // 該站點非簡單請求

 

 

 

CORS與JSONP都是用於跨域的,可是更爲強大,支持全部類型的HTTP請求;

而JSONP的優點在於支持老式瀏覽器,以及向不支持CORS的網站去請求數據

相關文章
相關標籤/搜索