1. 程式人生 > 其它 >postMessage和iframe的使用 跨域 跨視窗 瀏覽器子頁面 iframe子頁面

postMessage和iframe的使用 跨域 跨視窗 瀏覽器子頁面 iframe子頁面

postMessage和iframe的使用
https://www.jianshu.com/p/fd138d44fda5

客戶端與伺服器傳值還有幾個經常會遇到的問題

1.頁面和其開啟的新視窗的資料傳遞
2.多視窗之間訊息傳遞
3.頁面與巢狀的iframe訊息傳遞
4.上面三個問題的跨域資料傳遞

1.postMessage()

這些問題都有一些解決辦法,但html5引入的message的API可以更方便、有效、安全的解決這些難題。postMessage()方法允許來自不同源的指令碼採用非同步方式進行有限的通訊,可以實現跨文字檔、多視窗、跨域訊息傳遞。

postMessage(data,origin)方法接受兩個引數

1.data:要傳遞的資料,html5規範中提到該引數可以是JavaScript的任意基本型別或可複製的物件,然而並不是所有瀏覽器都做到了這點兒,部分瀏覽器只能處理字串引數,所以我們在傳遞引數的時候需要使用JSON.stringify()方法對物件引數序列化,在低版本IE中引用json2.js可以實現類似效果。
2.origin:字串引數,指明目標視窗的源,協議+主機+埠號[+URL],URL會被忽略,所以可以不寫,這個引數是為了安全考慮,postMessage()方法只會將message傳遞給指定視窗,當然如果願意也可以建引數設定為"*",這樣可以傳遞給任意視窗,如果要指定和當前視窗同源的話設定為"/"。

2.iframe

兩個基本概念:

主頁面指的是巢狀iframe的頁面
子頁面指的是被巢狀的iframe頁面

2.1 在主頁面,想要操作子頁面的DOM元素

contentWindow 相容各個瀏覽器,可取得子視窗的 window 物件。
contentDocument Firefox 支援,> ie8 的ie支援,可取得子視窗的 document 物件。

var ifr = document.getElementById("iframe");    // 先獲取iframe物件,此時的window是主頁面的window物件
ifr.contentWindow.document.
getElementById("div1") //獲取子頁面iframe的window物件,此時ifr.contentWindow返回的是iframe的window物件,後面可以繼續呼叫document方法 <iframe src="test.html" id=""></iframe> // 獲取要操作的子頁面的DOM元素
2.2 相容獲取document物件:
var getIFrameDoc = function(){
    var ifr = document.createElement("iframe");
    document.getElementsByTagName("body")[0].appendChild(ifr);
    return ifr.contentDocument || ifr.contentWindow.document;
}
2.3 在子頁面,要操作主頁面的DOM元素

window.parent 在iframe頁面通過parent可以獲得主頁面的window,接著就可以正常訪問父親頁面的元素了;
window.top() 這裡的top是獲取頂層的window,當有多層iframe巢狀的時候使用

var ifr = document.getElementByTagName("iframe");
ifr.parent.document.getElementById("div1")
<iframe src="test.html" id=""></iframe>

3.一些基本使用:

1,document.getElementById("myiframe").contentWindow 得到iframe物件後,就可以通過contentWindow得到iframe包含頁面的window物件,然後就可以正常訪問頁面元素了;
2, $("#myiframe")[0].contentWindow jquery選擇器獲得iframe,先把jquery物件轉換為DOM物件,或者使用get()方法轉換;
3,$("#myiframe")[0].contentWindow.$("#div1").val()可以在得到iframe的window物件後接著使用jquery選擇器進行頁面操作;
4,$("#myiframe")[0].contentWindow.username="starry";可以通過這種方式向iframe頁面傳遞引數,在iframe頁面window.username就可以獲取到值,username是自定義的全域性變數;
5,在iframe頁面通過parent可以獲得主頁面的window,接著就可以正常訪問父親頁面的元素了;
6,parent.$("#frameA")[0].contentWindow.document.getElmentById("#frameB"); 同級iframe頁面之間呼叫,需要先得到父親的window,然後呼叫同級的iframe得到window進行操作;