跨域:因爲瀏覽器的同源策略,屬於不一樣域的頁面之間不能相互訪問各自的頁面內容。web
開發中後臺項目,咱們首先須要讓本地服務run起來,起一個如http://localhost:8000/scg/show
這樣的頁面,而後,當咱們須要進行網絡交互時,一般使用相對域名,如/scg/search.json?pageNo=1
, 假設項目的代理配置以下chrome
那麼當請求/scg/search.json?pageNo=1
時,代理轉發出去的請求的是http://ottscg.alibaba.net/scg/search.json?pageNo=1, localhost去請求ottscg.alibaba.net中的內容,這時就發生了跨域。json
瀏覽器經過代理髮出CORS請求時,會在頭信息之中,增長一個Origin
字段,表示本次請求來自哪一個源(協議 + 域名 + 端口)。服務器根據這個值,決定是否贊成此次請求。若是Origin指定的源,不在許可範圍內,服務器會返回一個正常的HTTP迴應。瀏覽器發現,這個迴應的頭信息沒有包含Access-Control-Allow-Origin字段,就知道出錯了,從而拋出一個錯誤,被XMLHttpRequest的onerror回調函數捕獲。跨域
若是Origin指定的域名在許可範圍內,服務器返回的響應,會多出幾個以"Access-Control"開頭的頭信息字段,爲了發送帶cookie的跨域請求,咱們首先須要關心的是Access-Control-Allow-Origin
和Access-Control-Allow-Credentials
:瀏覽器
這個頭是容許CORS時,必須返回的頭,它的值要麼是請求時Origin字段的值,要麼是一個*,表示接受任意域名的請求。bash
默認狀況下瀏覽器對跨域請求不會攜帶 Cookie,但鑑於 Cookie 在身份驗證等方面的重要性, CORS 推薦使用額外的響應頭字段來容許跨域發送 Cookie。 這是一個可選的頭,若發送帶cookie的請求,則必須返回這個頭,並設置爲true,表示服務器容許客戶端發送Cookie。 須要注意的是,這個頭被設置爲true時,Access-Control-Allow-Origin不容許使用*,並且只能指定單一域名,不然瀏覽器會報以下錯誤。服務器
綜上, 發送cookie的CORS的正確姿式是:cookie
Access-Control-Allow-Origin: Origin;
Access-Control-Allow-Credentials : true
複製代碼
The include part tells Chrome that you want to send a CORS request to the server which sends along the cookies properly網絡
經過了解CORS原理,咱們知道了不支持CORS的服務端會返回一個正常的HTTP迴應,只是因爲沒有Aceess-control相關的響應頭,致使瀏覽器對響應進行了攔截。利用chrome.webRequest API,對onHeadersReceived進行監聽,便可在每次接收到 HTTP(S) 響應標頭時,添加須要的header字段,讓瀏覽器覺得這些頭信息是服務端返回的,從而繞過CORS限制。app
//Breaking the CORS Limitation
chrome.webRequest.onHeadersReceived.addListener(details=>window.onHeadersReceivedCallback(details), {
urls: ['<all_urls>']
}, ["blocking", "responseHeaders"]);
複製代碼
只設置Access-Control-Allow-Origin和Access-Control-Allow-Crendentials兩個字段,並不能知足全部的場景。例如,咱們在使用Antd的Upload組件進行上傳圖片時,Chrome會報以下錯誤:
Access-Control-Allow-Origin響應頭字段能夠容許跨域 AJAX, 但對於非簡單請求,CORS 機制跨域會首先進行 preflight(一個 OPTIONS 請求,表示這個請求是用來詢問的)
具體是指請求方法是簡單方法且請求頭是簡單頭的 HTTP 請求。具體地,
Access-Control-Request-Headers 是 preflight 請求中用來標識真正請求將會包含哪些頭部字段, 例以下述請求中Access-Control-Request-Headers字段的值是x-requested-with,告知服務器,實際請求將攜帶這個自定義請求首部字段。服務器據此決定,該實際請求是否被容許,若是容許,服務器應當在對應的Access-Control-Allow-Headers響應頭中包含這個字段。 不然即便返回 200 preflight 也會失敗。
查看Antd Upload組件的源碼,咱們看到,在上傳圖片時,增長了x-requested-with請求頭,由此觸發了非簡單請求,會在CORS時先進行Option詢問
綜上,爲了處理非簡單請求下的CORS,除了Access-Control-Allow-Origin和Access-Control-Allow-Crendentials外,咱們還須要在Header劫持中添加以下配置
Access-Control-Allow-Methods:"*",
Access-Control-Allow-Headers:"Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
複製代碼