Cross-Origin Resource Sharing(CORS)詳解,CORS詳解,CORS原理分析


Keywords CORS, 跨域,JS跨域調用,Ajax CORS 跨域,跨域詳解,CORS跨域原理

Cross-Origin Resource Sharing詳解

Cross-Origin Resource Sharing 通常簡稱為:CORS。它是一種機制,這個機制使用了一個額外的HTTP響應頭來賦予當前user-agent(瀏覽器)獲得在當前源(origin)下使用非同源資源權限。這句話聽起來很拗口,不易理解。但是請注意加粗字體所標記的兩個關鍵字,這里的非同源就是Cross-Origin的概念,這里邊的權限就是訪問非同源的資源權限。下面我們弄清楚了這兩個關鍵字的概念就理解了什么是Cross-Origin Resource Sharing。

從一個例子說起

假設我們現在在瀏覽器中輸入 http://www.myapp.com/index.html 請求index.html頁面。index.html中有一些文字信息,有一張圖片
http://www.somecloud.com/images/a.jpg ,和一個css文件 http://www.somecnd.com/a.css 。同時index.html的script節點中有如下的一個JavaScript方法。那么,圖片、樣式是否能夠正常顯示,getCrossRescource方法是否能正常執行呢?

function getCrossRescource () {
  $.ajax({
     url:"http://www.other.com/goods.json",
     success:function(){
       // do something 
     }
  });
}

以chrome瀏覽器為例,假設我們開發者工具,然后在瀏覽器中輸入上面的鏈接,我們可以看到,圖片正常顯示,樣式也正常渲染。但是getCrossRescource ()方法並未執行成功。我們在開發者工具的制台面板里邊會看到錯誤信息:

Failed to load :http://www.other.com/goods.json

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.myapp.com is therefore not allowed access.

通過錯誤信息我們得知:因為請求的資源不允許當前源https://www.myapp.com 訪問,因為沒有Access-Control-Allow-Origin頭信息,為什么呢?

這是因為:出於安全的原因,瀏覽器限制從腳本內發起跨源的HTTP請求,也就意味着限定了當前web應用程序只能請求與當前同域(同源)的HTTP資源,除非使用CORS頭信息。——原來被瀏覽器限制了。那么那些請求會被限制呢?

  • 以跨站點的方式調用XMLHttpRequest或者Fetch API。
  • Web字體(用於CSS中@ font-face的跨域字體使用)
  • WebGL textures
  • 使用drawImage繪制到canvas的圖像/視頻幀。
  • 樣式表(用於CSSOM訪問)

可以看到XMLHttpRequest遵循這個規則,而我們通常所使用的ajax方法就是基於XMLHttpRequest來實現的,所以在沒有使用CORS頭信息的的情況,跨源的getCrossRescource ()方法自然會無法順利執行。而上文所提到的index.html里跨源的a.jpg、a.css不屬於攔截目標,所以能夠正常顯示和渲染。

說到這里我們弄清楚了機制的問題。這個機制約定了同源的問題,並阻止了規定的這些請求形式。還剩下一個同源的概念需要解釋,那么什么叫做同源,什么叫做非同源呢?

同源的定義

給定兩個頁面,如果它們的協議、端口(如果指定了端口)、host都相同,則稱之為同源。現在給出一個源連接和一些其他連接與這個源的比較,結合下表,我們來實際的理解一下這個概念。

http://store.company.com/dir/page.html:

URL 是否同源 原因
http://store.company.com/dir2/other.html
http://store.company.com/dir/inner/another.html
https://store.company.com/secure.html 協議不同
http://store.company.com:81/dir/etc.html 端口不同
http://news.company.com/dir/other.html host不同

CROS頭信息設置

以上文中的例子來說明,我們訪問的是 http://www.myapp.com/index.html 頁面,那么當前的origin就是 http://www.myapp.com。 而這個頁面中的腳步請求的資源是 http://www.other.com/goods.json ,根據上文介紹的信息我們可以得知:這個是非同源的請求,且屬於瀏覽器攔截名單里邊的請求形式。所以我們需要通過設置CROS頭信息來完成跨域調用。

Access-Control-Allow-Origin 頭信息設置

本例中,我們需要在http://www.other.com/goods.json所對應的服務器代碼中加入響應頭:

Access-Control-Allow-Origin: http://www.myapp.com

設置完之后,當前的源http://www.myapp.com獲得了訪問數據的權限。這個時候我們可以在請求/響應頭信息看到多了一些信息,大致如下:

GET /...
Host: ...
User-Agent:  ...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://www.myapp.com/index.html
Origin: http://www.myapp.com

--------------------------
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61 
Access-Control-Allow-Origin: http://www.myapp.com
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

使用JSONP解決跨域

除了使用設置CORS頭信息,我們還可以使用JSONP來實現跨域調用。以Jquery為例,我們可以使用如下的寫法來調用跨域資源:

function corsTest(){
    $.ajax({
        type: "get",
        url: "http://other.host/data.json",
        dataType:"jsonp",
      	jsonp:"callback",
      	jsonpCallback:"callBack",
        ......
    })
}
function callBack(data){
    // do something
    ......
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM