js跨域

一.跨域是什麼:

跨域就是:JavaScript出於安全方面的考慮,不容許跨域調用其餘頁面的對象。css

但在安全限制的同時也給注入iframe或是ajax應用上帶來了很多麻煩。html

簡單地理解就是由於JavaScript同源策略的限制,a.com 域名下的js沒法操做b.com或是c.a.com域名下的對象。前端

二.跨域的表現:

跨域的表現主要有:協議不一樣,主機名不一樣,端口號不一樣node

詳細的說明能夠看下錶:ajax

URL 說明 是否容許通訊
http://www.a.com/a.js
http://www.a.com/b.js
同一域名下 容許
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
同一域名下不一樣文件夾 容許
http://www.a.com:8000/a.js
http://www.a.com/b.js
同一域名,不一樣端口 不容許
http://www.a.com/a.js
https://www.a.com/b.js
同一域名,不一樣協議 不容許
http://www.a.com/a.js
http://70.32.92.74/b.js
域名和域名對應ip 不容許
http://www.a.com/a.js
http://script.a.com/b.js
主域相同,子域不一樣 不容許
http://www.a.com/a.js
http://a.com/b.js
同一域名,不一樣二級域名(同上) 不容許(cookie這種狀況下也不容許訪問)
http://www.cnblogs.com/a.js
http://www.a.com/b.js
不一樣域名 不容許

特別注意兩點:json

第一,若是是協議和端口形成的跨域問題「前臺」是無能爲力的,跨域

第二:在跨域問題上,域僅僅是經過「URL的首部」來識別而不會去嘗試判斷相同的ip地址對應着兩個域或兩個域是否在同一個ip上。
「URL的首部」指window.location.protocol +window.location.host,也能夠理解爲「Domains, protocols and ports must match」。安全

 三.解決跨域的方法(前端):

 1.JSONP:

JSONP包含兩部分:回調函數和數據。服務器

回調函數是當響應到來時要放在當前頁面被調用的函數。cookie

數據就是傳入回調函數中的json數據,也就是回調函數的參數了。

function handleResponse(response){
    console.log('The responsed data is: '+response.data);
}
var script = document.createElement('script');
script.src = 'http://www.baidu.com/json/?callback=handleResponse';
document.body.insertBefore(script, document.body.firstChild);
/*handleResonse({"data": "zhe"})*/
//原理以下:
//當咱們經過script標籤請求時
//後臺就會根據相應的參數(json,handleResponse)
//來生成相應的json數據(handleResponse({"data": "zhe"}))
//最後這個返回的json數據(代碼)就會被放在當前js文件中被執行
//至此跨域通訊完成

 2.iframe跨域:

對於主域相同而子域不一樣的例子,能夠經過設置document.domain的辦法來解決。具體的作法是能夠在http://www.a.com/a.html和http://script.a.com/b.html兩個文件中分別加上document.domain = ‘a.com’;而後經過a.html文件中建立一個iframe,去控制iframe的contentDocument,這樣兩個js文件之間就能夠「交互」了。固然這種辦法只能解決主域相同而二級域名不一樣的狀況,若是你異想天開的把script.a.com的domian設爲alibaba.com那顯然是會報錯地!代碼以下:

www.a.com上的a.html

document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.a.com/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
    var doc = ifr.contentDocument || ifr.contentWindow.document;
    // 在這裏操縱b.html
    alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};

script.a.com上的b.html

document.domain = 'a.com';    

這種方式適用於{www.kuqin.com, kuqin.com, script.kuqin.com, css.kuqin.com}中的任何頁面相互通訊。

備註:某一頁面的domain默認等於window.location.hostname。主域名是不帶www的域名,例如a.com,主域名前面帶前綴的一般都爲二級域名或多級域名,例如www.a.com實際上是二級域名。 domain只能設置爲主域名,不能夠在b.a.com中將domain設置爲c.a.com。

3.script元素的src屬性處理:

   iframe、img、style、script等元素的src屬性能夠直接向不一樣域請求資源,jsonp正是利用script標籤跨域請求資源的簡單實現,因此這個和jsonp本質同樣,一樣須要服務端請求返回callback...形式。

var url="http://xxx.xxx.xxx?p1=1";
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);

4.Flash:

flash在跨域時惟一的限制策略就是crossdomain.xml文件,該文件限制了flash是否能夠跨域讀寫數據以及容許從什麼地方跨域讀寫數據。

位於www.a.com域中的SWF文件要訪問www.b.com的文件時,SWF首先會檢查www.b.com服務器目錄下是否有crossdomain.xml文件,若是沒有,則訪問不成功;若crossdomain.xml文件存在,且裏邊設置了容許www.a.com域訪問,那麼通訊正常。因此要使Flash能夠跨域傳輸數據,其關鍵就是crossdomain.xml。

4.1 crossdomain.xml的放置位置

自flash 10之後,若有跨域訪問需求,必須在目標域的根目錄下放置crossdomain.xml文件,且該根目錄下的配置文件稱爲「主策略文件」。若不存在主策略文件,則該域將禁止任何第三方域的flash跨域請求。

主策略文件對全站的跨域訪問起控制做用。

也能夠單獨在某路徑下放置僅對該路徑及其子路徑生效的crossdomain.xml配置文件,這須要在flash的AS腳本中使用以下語句來加載該配置文件:[具體的加載權限限制,將受後文中site-control策略的影響]

Security.loadPolicyFile("http://www.xxx.com/subdir/crossdomain.xml")

4.2 crossdomain.xml的配置方法及影響

crossdomain.xml需嚴格遵照XML語法,有且僅有一個根節點cross-domain-policy,且不包含任何屬性。在此根節點下只能包含以下的子節點:site-control、allow-access-from、allow-access-from-identity、allow-http-request-headers-from。下面將分別介紹這四個子節點:

4.2.1site-control經過檢查該節點的屬性值,確認是否能夠容許加載其餘策略文件。[若是該策略文件並不是主策略文件,則此節點被自動忽略]

每一個site-control標籤有且僅有屬性permitted-cross-domain-policies,該屬性指定相對於非主策略文件的其餘策略文件的加載策略。permitted-cross-domain-policies屬性值有以下狀況:

none: 不容許使用loadPolicyFile方法加載任何策略文件,包括此主策略文件。

master-only: 只容許使用主策略文件[默認值]。

by-content-type:只容許使用loadPolicyFile方法加載HTTP/HTTPS協議下Content-Type 爲text/x-cross-domain-policy的文件做爲跨域策略文件。

by-ftp-filename:只容許使用loadPolicyFile方法加載FTP協議下文件名爲       crossdomain.xml的文件做爲跨域策略文件。

all: 可以使用loadPolicyFile方法加載目標域上的任何文件做爲跨域策略文件,甚至是一 個JPG也可被加載爲策略文件![使用此選項那就等着被xx吧!]

如須要對網站某子目錄作單獨的flash跨域限制策略,在主策略文件中必須進行相應的site-control設置。

下面的例子將site-control策略配置爲可加載本服務器中其它的text/x-cross-domain-policy文件做爲跨域策略文件。

<cross-domain-policy> 

     <site-control permitted-cross-domain-policies="by-content-type" /> 

</cross-domain-policy>

4.2.2 allow-access-from經過檢查該節點的屬性值,確認可以讀取本域內容的flash文件來源域。

allow-access-from標籤有三個屬性:

·domain該屬性指定一個確切的 IP 地址、一個確切的域或一個通配符域(任何域)。只有domain中指定的域,纔有權限經過flash讀取本域中的內容。

可採用下列兩種方式之一來表示通配符域:

1.單個星號(*),如:<allow-access-fromdomain="*" />,表示匹配全部域和全部IP 地     址,此時任何域都可跨域訪問本域上的內容。[這是極不安全的!]

2.後接後綴的星號,表示只匹配那些以指定後綴結尾的域,如*.qq.com可匹配            game.qq.com、qq.com。形如www.q*.com或www.qq.*的爲無效配置。

Tips當domain被指定爲IP地址時,只接受使用該IP做爲網址來訪問的來源請求[此時ip地址也就至關於一個域名而已],如domain被設置爲192.168.1.100時,使用http://192.168.1.100/flash.swf 來請求該域內容是容許的,可是使用指向192.168.1.100的域名www.a.com來訪問時[http://www.a.com/flash.swf]將會被拒絕,由於flash不懂得dns解析:)

·to-ports該屬性值代表容許訪問讀取本域內容的socket鏈接端口範圍。可以使用to-ports="1100,1120-1125"這樣的形式來限定端口範圍,也可以使用通配符(*)表示容許全部端口。

·secure該屬性值指明信息是否經加密傳輸。當crossdomain.xml文件使用https加載時,secure默認設爲true。此時將不容許flash傳輸非https加密內容。若手工設置爲false則容許flash傳輸非https加密內容。

下面的例子配置爲容許全部qq.com下的全部二級域名[包括qq.com自己]經過https訪問本域中的內容。

<cross-domain-policy> 

     <allow-access-from domain="*.qq.com" secure="true" /> 

</cross-domain-policy>

4.2.3allow-access-from-identity該節點配置跨域訪問策略爲容許有特定證書的來源跨域訪問本域上的資源。每一個allow-access-from-identity節點最多隻能包含一個signatory子節點。形如:

<allow-access-from-identity>

   <signatory>

     <certificate

       fingerprint="01:23:45:67:89:ab:cd:ef:01:23:45:67:89:ab:cd:ef:01:23:45:67"

       fingerprint-algorithm="sha-1"/>

   </signatory>

</allow-access-from-identity>

4.2.4allow-http-request-headers-from此節點受權第三方域flash向本域發送用戶定義的http頭。

allow-access-from節點受權第三域提取本域中的數據,而 allow-http-request-headers-from 節點受權第三方域將數據以http頭的形式發送到本域中。[簡而言之,allow-access-from是控制讀取權限,allow-http-request-headers-from是控制以http頭形式的寫入權限]

allow-http-request-headers-from包含三個屬性:

·domain做用及參數格式與allow-access-from節點中的domain相似。

·headers以逗號隔開的列表,代表容許發送的http頭。可用通配符(*)表示所有    http頭。

·secure做用及用法與allow-access-from節點中的secure相同。

在下面的示例中,任何域均可以向當前域發送 SOAPAction 標頭:

<cross-domain-policy> 

     <allow-http-request-headers-from domain="*" headers="SOAPAction" /> 

</cross-domain-policy>

flash小總結

不正確的crossdomain.xml策略將致使嚴重的安全問題,如信息泄露、CSRF等。從上文中能夠看出,在進行安全評估時,咱們應重點關注如下幾點:

1.allow-access-from標籤的domain屬性檢測:domain屬性應根據最小化原則按需設置,僅容許可信任的來源跨域請求本域內容。禁止將該屬性值設置爲「*」。

2.allow-http-request-headers-from標籤的domain屬性檢測:domain屬性應根據最小化原則按需設置,僅容許可信任的來源向本域跨域發送內容。禁止將該屬性值設置爲「*」。

3. site-control標籤的permitted-cross-domain-policies屬性檢測:根據業務的實際需求及可行性,對該屬性作相應設置。禁止將該屬性值設置爲「all」。

相關文章
相關標籤/搜索