CORS 跨域, 也許這篇就夠了

CORS前奏

瞭解CORS跨域以前,也許咱們還應該對跨域這麼個東東的一些概念要有些瞭解。html

1. 什麼是跨域

廣義上的跨域是指一個 域下的文檔或腳本試圖去請求另外一個域下的資源。好比: 資源跳轉(a連接)、資源嵌入(link, script)、腳本請求(js發起ajax請求)等。而咱們一般所討論的跨域是指的是狹義上的跨域,指的是由瀏覽器同源策略限制的一類請求場景。那麼什麼是同源策略,同源策略又限制了什麼。html5

2. 什麼是同源策略

同源指的是若是兩個頁面的協議,端口和域名都相同,則兩個頁面具備相同的源,只要其中之一不一樣,則那這兩個源就不相同。git

3. 同源策略限制了什麼

  • Cookie、LocalStorage 和 IndexDB 沒法讀取。
  • DOM 沒法得到(內嵌iframe中,父子頁面不能獲取DOM)。
  • AJAX 請求不能發送。

4. 爲何有同源策略的限制

同源政策的目的,是爲了保證用戶信息的安全,防止惡意的網站竊取數據。github

  1. Cookie、LocalStorage 和 IndexDB 沒法讀取限制。(緣由好比:訪問一個惡意網站,獲取到全部網站下的cookie信息, 若是有某個已登陸的網站, 登陸驗證放在cookie裏, 那就能夠假裝你的身份去訪問該 網站。)
  2. DOM 沒法得到(內嵌iframe中,父子頁面不能獲取DOM)。(緣由好比:一個惡意 網站,iframe嵌入一個正規網站的, 這樣就能夠獲取到用戶的登陸信息和密碼。 )
  3. AJAX 請求不能發送。 (緣由好比: 沒限制直接就能夠用腳本把服務器給打爆了。)

5. 解決跨域的方法

  • JSONP
  • location.hash
  • document.domain
  • window.name
  • window.postMessage
  • WebSocket
  • CORS 接下來要重點討論下的是CORS是如何解決ajax請求跨域的。

CORS正文

CORS(跨域資源共享)是一種機制,容許 Web 應用服務器進行跨域訪問控制,從而使跨域數據傳輸得以安全進行。CORS的使用要瀏覽器和服務端同時支持,並配合使用, IE要大於10。ajax

1. 怎麼工做的

CORS請求過程
js中進行一個跨域的ajax請求,瀏覽器判斷該請求是簡單請求仍是複雜請求,簡單請求就直接發送, 複雜請求就先發送一次預檢請求, 預檢請求成功後, 再發送完整的請求, 整個過程對用戶是無感知的。那麼什麼是簡單請求和複雜請求呢?

2. CORS的簡單請求和複雜請求

簡單請求須要同時知足如下兩個條件:json

  • 請求是如下方法之一: GET、HEAD、POST
  • 不得人爲設置如下集合以外的其餘首部字段:
Accept
Accept-Language
Content-Language
Content-Type (須要注意額外的限制):
(text/plain
multipart/form-data
application/x-www-form-urlencoded)
複製代碼

非簡單請求就認爲是複雜請求(好比PUT、DELETE請求, content-type設置爲appliction/json等), 就須要發送預檢請求。跨域

3. CORS是如何工做的(如何肯定是否容許跨域)

肯定是否容許跨域就須要瀏覽器和服務器共同協做完成,主要就是經過特定的一些響應頭來完成。預檢請求還須要有特定的請求頭。那麼特定請求頭分別有哪些以及是如何配合使用的。瀏覽器

######a. 服務端響應頭緩存

  • Access-Control-Allow-Origin:這個字段是必須的,表明的是容許跨域的源, '*'表明任意的源。
  • Access-Control-Allow-Methods: 這個字段也是必須的, 表明容許跨域的http請求方法。
  • Access-Control-Allow-Credentials: 非必須的, 表示是否容許發送cookie, 默認是false,若是設置爲true則同時還須要客戶端要設置xhr.withCredentials = true才能起做用, 二者是共存的(其中的cookie帶的是目標域的cookie)。
  • Access-Control-Allow-Headers: 非必須的,表示容許的請求頭, 若是預檢請求中包括了Access-Control-Request-Headers, 則服務端必須設置該字段。
  • Access-Control-Max-Age:非必須的,用來指定本次預檢請求的有效期,單位爲秒。即將CORS的響應配置緩存在瀏覽器端, 在緩存生效時間內,下次請求不用發送預檢請求。 須要注意的是: 瀏覽器的disable-cache要關掉
  • Access-Control-Expose-Headers:可選字段, 客戶端只能根據響應獲取到如下的響應頭:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
複製代碼

若是想要獲取額外的響應頭信息, 則須要將其設置在這個字段中。安全

b. 客戶端預檢請求頭
  • Access-Control-Request-Method: 該字段是必須的,用來表示覽器的CORS請求會用到哪一個HTTP方法。
  • Access-Control-Request-Headers: 該字段是非必須的,指定瀏覽器CORS請求額外發送的頭信息字段。
針對簡單請求狀況:

不會發送預檢請求, 直接是發起真正的請求,只要 Access-Control-Allow-Origin與Access-Control-Allow-Methods正確的設置就能發起請求。

具體的coding例子:github傳送門

後記: 若是看完這篇還沒理解,那就。。。再多看幾遍(逃。。。),根據demo折騰下。

參考文章:

  1. www.ruanyifeng.com/blog/2016/0…
  2. www.html5rocks.com/en/tutorial…
  3. developer.mozilla.org/zh-CN/docs/…
  4. developer.mozilla.org/zh-CN/docs/…
  5. github.com/hijiangtao/…
相關文章
相關標籤/搜索