CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。當兩個地址scheme+host+port不一樣的時候,就是不一樣域的地址。html
cors是瀏覽器的策略,目的是爲了保證網絡上資源調用的安全性。若是瀏覽器僅僅是訪問資源,不會存在跨域問題,好比訪問圖片,JS等文件;可是若是是讀取元數據,就會受到瀏覽器CORS的限制,好比AJAX請求。前端
瀏覽器將CORS請求分紅兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。web
- 請求方法是如下三種方法之一:HEAD,GET,POST
- HTTP的頭信息不超出如下幾種字段:Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type: 只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
知足以上條件的爲簡單請求,不然爲非簡單請求(好比常見的自定義header字段,或是Content-Type:application/json等)。json
對於簡單請求,瀏覽器發送請求時會在request header裏添加Origin字段,標記請求源。服務器處理請求後,返回響應信息,瀏覽器檢查響應信息,發現響應頭裏沒有設置Access-Control-Allow-Origin等跨域信息,會攔截請求,並拋出錯誤。跨域
非簡單跨域請求在發送時,瀏覽器會增長一個options預檢請求。大概流程以下:瀏覽器
當非簡單請求裏添加過自定義請求頭字段,則 response 裏須要同步設置 Access-Control-Allow-Headers: '自定義header字段名',此時預檢請求才會校驗經過。緩存
// Request
headers: {
'Content-Type': 'application/json',
'system': 'web',
'version': 'v1.0'
}
複製代碼
// Response
'Access-Control-Allow-Headers': 'Content-Type, system, version'
複製代碼
跨域讀取cookie, 須要知足以下三個條件:安全
通常前端只能讀取resopnse body,若是想要讀取自定義的response header信息,就須要設置Access-Control-Expose-Headers字段,指定須要暴露出去的header字段,這樣前端就能夠經過JS來讀取響應頭裏的header信息了。服務器
// js
let system = response.headers.get('system');
複製代碼
// response
Access-Control-Expose-Headers: 'system'
複製代碼
若是某個請求類型是delete,則響應頭裏須要設置Access-Control-Allow-Methods字段。markdown
// response
Access-Control-Allow-Methods: 'delete'
複製代碼
可使用 Access-Control-Max-Age 設置預檢請求的有效期。在這段時間內,同個請求的預檢請求只會請求一次。
// response
Access-Control-Max-Age: 100 // 100秒內使用緩存過的預檢請求
複製代碼
值爲 * 或是固定的域名,表示容許跨域請求的域名。
值爲 true/false,表示服務器是否接收Cookie。想要跨域傳遞cookie,除了服務端Access-Control-Allow-Credentials: true接收cookie外;客戶端請求也須要設置withCredentials: true,表示瀏覽器贊成發送cookie。另外 Access-Control-Allow-Origin 必須是個指定的域名。
值爲請求頭裏設置的自定義header字段。
值爲須要暴露出去的header字段。
跨來源的請求只接受三種類型GET、HEAD,POST。除此以外,若是是其它請求類型,則響應頭裏須要設置Access-Control-Allow-Methods: 'xxx'。
Access-Control-Max-Age 指定本次預檢請求的有效期,單位是秒。