天天看點

javascript跨域的幾種方法

以下的例子包含的檔案均為為 

http://www.a.com/a.html

 、

http://www.a.com/c.html

 與 

http://www.b.com/b.html

,要做的都是從

a.html

擷取

b.html

裡的資料

1.JSONP

jsonp

是利用

script

标簽沒有跨域限制的特性,通過在

src

url

的參數上附加回調函數名字,然後伺服器接收回調函數名字并傳回一個包含資料的回調函數

function doSomething(data) {
        // 對data處理
    }
    var script = document.createElement("script");
    script.src = "http://www.b.com/b.html?callback=doSomething";
    document.body.appendChild(script);

    // 1.生成一個script标簽,将其append在body上,向伺服器送出請求
    // 2.伺服器根據 callback 這個參數生成一個包含資料的函數 doSomething({"a", "1"})
    // 3.頁面事先已聲明doSomething函數,此時執行 doSomething(data) 這個函數,獲得資料      

2.HTML5的postMessage

假設在

a.html

裡嵌套個

<iframe src="http://www.b.com/b.html" frameborder="0"></iframe>

,在這兩個頁面裡互相通信

a.html
window.onload = function() {
        window.addEventListener("message", function(e) {
            alert(e.data);
        });

        window.frames[0].postMessage("b data", "http://www.b.com/b.html");
    }      
b.html
window.onload = function() {
        window.addEventListener("message", function(e) {
            alert(e.data);
        });
        window.parent.postMessage("a data", "http://www.a.com/a.html");
    }      

這樣打開

a

頁面就先彈出 

a data

,再彈出 

b data

3.window.name + iframe

window.name

的原理是利用同一個視窗在不同的頁面共用一個

window.name

,這個需要在

a.com

下建立一個代理檔案

c.html

,使同源後

a.html

能擷取

c.html

window.name

var iframe = document.createElement("iframe");
    iframe.src = "http://www.b.com/b.html";
    document.body.appendChild(iframe); // 現在a.html裡建一個引用b.html的iframe,獲得b的資料

    var flag = true;
    iframe.onload = function() {
        if (flag) {
            iframe.src = "c.html";  
// 判斷是第一次載入的話,設定代理c.html使和a.html在同目錄同源,這樣才能在下面的else取到data
            flag = false;
        } else { // 第二次載入由于a和c同源,a可以直接擷取c的window.name
            alert(iframe.contentWindow.name);

            iframe.contentWindow.close();
            document.body.removeChild(iframe);
            iframe.src = '';
            iframe = null;
        }
    }      
window.name = "這是 b 頁面的資料";      

4.window.location.hash + iframe

b.html

将資料以

hash

值的方式附加到

c.html

url

上,在

c.html

頁面通過

location.hash

擷取資料後傳到

a.html

(這個例子是傳到

a.html

hash

上,當然也可以傳到其他地方)

var iframe = document.createElement("iframe");
    iframe.src = "http://www.b.com/b.html";
    document.body.appendChild(iframe); // 在a頁面引用b
    function check() { // 設定個定時器不斷監控hash的變化,hash一變說明資料傳過來了
        var hashs = window.location.hash;
        if (hashs) {
            clearInterval(time);
            alert(hashs.substring(1));
        }
    }
    var time = setInterval(check, 30);      
window.onload = function() {
        var data = "this is b's data"; 
        var iframe = document.createElement("iframe");
        iframe.src = "http://www.a.com/c.html#" + data;
        document.body.appendChild(iframe); // 将資料附加在c.html的hash上
    }      
c.html
// 擷取自身的hash再傳到a.html的hash裡,資料傳輸完畢
parent.parent.location.hash = self.location.hash.substring(1);       

5.CORS

CORS

XMLHttpRequest Level 2

 裡規定的一種跨域方式。在支援這個方式的浏覽器裡,

javascript

的寫法和不跨域的

ajax

寫法一模一樣,隻要伺服器需要設定

Access-Control-Allow-Origin: *

6.document.domain

這種方式适用于主域相同,子域不同,比如

http://www.a.com

http://b.a.com

假如這兩個域名下各有

a.html

 和

b.html

,

document.domain = "a.com";
    var iframe = document.createElement("iframe");
    iframe.src = "http://b.a.com/b.html";
    document.body.appendChild(iframe);
    iframe.onload = function() {
        console.log(iframe.contentWindow....); // 在這裡操作b.html裡的元素資料
    }      
document.domain = "a.com";      

注意:

document.domain

需要設定成自身或更高一級的父域,且主域必須相同。