平時做web開發的時候關於消息傳遞,除了客戶端與服務器傳值還有幾個經常會遇到的問題
- 頁面和其打開的新窗口的數據傳遞
- 頁面與嵌套的iframe消息傳遞
這些問題都有一些解決辦法,但html5引入的message的API可以更方便、有效、安全的解決這些難題。
postMessage()方法允許來自不同源的腳本采用異步方式進行有限的通信,可以實現跨文本檔、多窗口、跨域消息傳遞。
語法
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
其他窗口的一個引用,比如iframe的contentWindow屬性、執行window.open返回的窗口對象、或者是命名過或數值索引的window.frames。
message
將要發送到其他 window的數據。
targetOrigin
通過窗口的origin屬性來指定哪些窗口能接收到消息事件,其值可以是字符串'*'(表示無限制)或者一個URI。在發送消息的時候,如果目標窗口的協議、主機地址或端口這三者的任意一項不匹配targetOrigin提供的值,那么消息就不會被發送;只有三者完全匹配,消息才會被發送。這個機制用來控制消息可以發送到哪些窗口;例如,當用postMessage傳送密碼時,這個參數就顯得尤為重要,必須保證它的值與這條包含密碼的信息的預期接受者的origin屬性完全一致,來防止密碼被惡意的第三方截獲。如果你明確的知道消息應該發送到哪個窗口,那么請始終提供一個有確切值的targetOrigin,而不是*。不提供確切的目標將導致數據泄露到任何對數據感興趣的惡意站點。
例子
現在有2個網站頁面,分別是http://testA.com/A.html和http://testB.com/B.html
// A.html嵌套B.html
// A.html
// A向B傳遞消息
window.onload = function () {
window.frames[0].postMessage('getcolor', 'http://testB.com');
}
// A接收B的消息
window.addEventListener('message', function (e) {
if (e.source != 'http://testB.com') return;
alert(JSON.stringify(e));
}, false);
// B.html
// B向A傳遞消息
function Send () {
window.parent.postMessage(color, 'http://testA.com');
}
// B接收A的消息
window.addEventListener('message', function (e) {
if (e.source != 'http://testA.com') return;
alert(JSON.stringify(e));
}, false);
// A.html新開窗口B.html
// A.html
// A向B傳遞消息
let win = null;
window.onload = function () {
win = window.open('http://testB.com');
}
function Send () {
win.postMessage(color, 'http://testB.com');
}
// A接收B的消息
window.addEventListener('message', function (e) {
if (e.source != 'http://testB.com') return;
alert(JSON.stringify(e));
}, false);
// B.html
// B向A傳遞消息
function Send () {
window.opener.postMessage(color, 'http://testA.com');
}
// B接收A的消息
window.addEventListener('message', function (e) {
if (e.source != 'http://testA.com') return;
alert(JSON.stringify(e));
}, false);
