說明
window.postMessage()方法可以安全地實(shí)現(xiàn)Window對(duì)象之間的跨域通信。例如懈费,在一個(gè)頁面和它生成的彈出窗口之間渐溶,或者是頁面和嵌入其中的iframe之間畅厢。
通常情況下业崖,不同頁面上的腳本允許彼此訪問,當(dāng)且僅當(dāng)它們?cè)醋缘捻撁婀蚕硐嗤膮f(xié)議呜师,端口號(hào)和主機(jī)(也稱為“同源策略”)娶桦。window.postMessage()提供了一個(gè)受控的機(jī)制來安全地規(guī)避這個(gè)限制(如果使用得當(dāng)?shù)脑挘?/p>
一般來說,一個(gè)窗口可以獲得對(duì)另一個(gè)窗口的引用(例如汁汗,通過targetWindow=window.opener)趟紊,然后使用targetWindow.postMessage()在其上派發(fā)MessageEvent。接收窗口隨后可根據(jù)需要自行處理此事件碰酝。傳遞給window.postMessage()的參數(shù)通過事件對(duì)象暴露給接收窗口霎匈。
發(fā)送端
postMessage程序
var receiver = document.getElementById('receiver').contentWindow;
var btn = document.getElementById('send');
btn.addEventListener('click', function (e) {
e.preventDefault();
var val = document.getElementById('text').value;
receiver.postMessage("Hello "+val+"!", "http://res.42du.cn");
});
發(fā)送消息的基本語法:
targetWindow.postMessage(message, targetOrigin, [transfer]);
targetWindow
targetWindow就是接收消息的窗口的引用送爸。 獲得該引用的方法包括:
- Window.open
- Window.opener
- HTMLIFrameElement.contentWindow
- Window.parent
- Window.frames +索引值
message
message就是要發(fā)送到目標(biāo)窗口的消息铛嘱。 數(shù)據(jù)使用結(jié)構(gòu)化克隆算法進(jìn)行序列化暖释。 這意味著我們可以將各種各樣的數(shù)據(jù)對(duì)象安全地傳遞到目標(biāo)窗口,而無需自己對(duì)其進(jìn)行序列化墨吓。
targetOrigin
targetOrigin就是指定目標(biāo)窗口的來源球匕,必須與消息發(fā)送目標(biāo)相一致,可以是字符串“*”或URI帖烘。 *表示任何目標(biāo)窗口都可接收亮曹,為安全起見,請(qǐng)一定要明確提定接收方的URI秘症。
transfer
transfer是可選參數(shù)
接收端
目標(biāo)窗口通過執(zhí)行下面的JavaScript來偵聽發(fā)送過來的消息:
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event){
if (event.origin !== "http://www.42du.cn")
return;
}
event對(duì)象有三個(gè)屬性照卦,分別是origin,data和source乡摹。event.data表示接收到的消息役耕;event.origin表示postMessage的發(fā)送來源,包括協(xié)議聪廉,域名和端口瞬痘;event.source表示發(fā)送消息的窗口對(duì)象的引用; 我們可以用這個(gè)引用來建立兩個(gè)不同來源的窗口之間的雙向通信。
完整程序
發(fā)送程序
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>42度空間-window.postMessage()跨域消息傳遞</title>
</head>
<body>
<div>
<input id="text" type="text" value="42度空間" />
<button id="send" >發(fā)送消息</button>
</div>
<iframe id="receiver" src="http://res.42du.cn/static/html/receiver.html" width="500" height="60">
<p>你的瀏覽器不支持IFrame板熊。</p>
</iframe>
<script>
window.onload = function() {
var receiver = document.getElementById('receiver').contentWindow;
var btn = document.getElementById('send');
btn.addEventListener('click', function (e) {
e.preventDefault();
var val = document.getElementById('text').value;
receiver.postMessage("Hello "+val+"框全!", "http://res.42du.cn");
});
}
</script>
</body>
</html>
接收程序
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>42度空間-從www.42du.cn接收消息</title>
</head>
<body>
<div id="message">
Hello World!
</div>
<script>
window.onload = function() {
var messageEle = document.getElementById('message');
window.addEventListener('message', function (e) {
alert(e.origin);
if (e.origin !== "http://www.42du.cn") {
return;
}
messageEle.innerHTML = "從"+ e.origin +"收到消息: " + e.data;
});
}
</script>
</body>
</html>
演示地址
[跨域消息傳遞](http://www.42du.cn/paper/11)