javascript 跨域問題解決辦法總結


逼你退出

跨域的意思就是不同域名之間的頁面默認是無法通信的。因為瀏覽器默認是禁止跨域的;

 

 

圖所示:chrome瀏覽器嘗試獲取mainFrame失敗,提示DomException

 

image

 

image

 

 

 

 

 

1).假如你有個網站 a.com 中有個iframe的連接指向的是http://www.baidu.com,那么你想獲取iframe中元素id為text1的值,通過js是無法獲取到的。

   辦法: location.hash ,ifame  

 

2).再換一種情況。 a.a.com 中有個iframe的src指向的是b.a.com,同家族a.com下的不同2級域名,在a.a.com中使用js也是無法獲取到b.a.com中的內容。

   辦法:document.domain+iframe

 

 

 

下面是常用的解決跨域的辦法

 

 

 

1..document.domain+iframe 的設置

適用同一家族下的2個子域名  a.a.com   ,b.a.com  以及a.com ,script.a.com

domain必須設置為a.com,及等於window.location.hostname

 

a.a.com 想引用 b.a.com html代碼中的值

可以在 a.a.com 和b.a.com下面都加上偽域名   a.com,接着在a.a.com中動態創建iframe

1)在b.b.com中加入

<script type=”text/javascript” >

document.domain = "a.com";

</script>

 

2)接着在a.a.com中加入script 代碼,通過 iframe的contextDocument獲取b.a.com中的值

<script type=”text/javascript” >

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.a.com通過下面代碼獲取b.a.com窗口的高度

var h = window.navigator.userAgent.indexOf("MSIE") > 0 ? document.body.scrollHeight : document.documentElement.scrollHeight;
parent.parent.document.getElementById('name').height = h;

 

 

兩個不同的子域名偽裝成了同域,完全在同源策略的保護下進行通信

 

 

2. location.hash ,ifame          (弊端:遠端的數據頁面,你要協調好,必須得放一段js)       

可以解決不同主域名下的數據通信,但是hash有長度限制,數據暴露,數據類型有限制

子窗口無法改變無窗口的hash值,除非是同一域名下的

 

www.baidu.com#abc  就是location.hash

 

假如a.com要使用b.com中的值。

1)首先a.com創建iframe,並指向 b.com#parms

 

a.com用js定時檢測iframe中src中的location.hash是否改變了,如果改變則獲取其值則獲取新location.hash值。

IE,chrome瀏覽器不支持跨域修改parent.location.hash值,所以需要代理。但是firefox支持修改。

 

a.com中的代碼

<script>

function startRequest(){
    var ifr = document.createElement('iframe');
    ifr.style.display = 'none';
    ifr.src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';   //根據paramdo來決定獲取啥值
    document.body.appendChild(ifr);
}

//每2秒檢測一次,是否變動了值
function checkHash() {
    try {
        var data = location.hash ? location.hash.substring(1) : '';
        if (console.log) //console.log javascript中調試輸出信息,比alert好

          {
            console.log('Now the data is '+data);
        }
    } catch(e) {};
}
setInterval(checkHash, 2000);

</script>

 

 

b.com頁面的代碼如下

//模擬一個簡單的參數處理操作
switch(location.hash){
    case '#paramdo':
        callBack();
        break;
    case '#paramset':
        //do something……
        break;
}
//設置a.com iframe src的location.hash
function callBack(){
    try {
//此時是火狐正常執行
        parent.location.hash = 'somedata';
    } catch (e) {
        // iechrome的安全機制無法修改parent.location.hash,
        // 所以要利用一個中間的cnblogs域下的代理iframe
        var ifrproxy = document.createElement('iframe');
        ifrproxy.style.display = 'none';
        ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata';    // 注意該文件在"a.com"域下
        document.body.appendChild(ifrproxy);
    }
}
 
 
a.com域名下 cs3.html中的代碼
 
//因為parent.parent和自身屬於同一個域,所以可以改變其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);

 

3. window.name  + ifame          (弊端:遠端的數據頁面,你要協調好,必須得放一段js)    

  http://www.cnblogs.com/StudyLife/p/3515357.html

 

總結:

location.hash 在 主頁面a.com中設置'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo'  (#paramdo為location.hash,不會隨頁面刷新改變)。並在a.com頁面js每隔一段時間就去檢測#paramdo是否被改變了,如果被改變了,說明獲取到數據了。


免責聲明!

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



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