html5引入message的API:postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。但是,这种消息传递机制必须是另一个页面在当前页中使用< iframe >引入,或者由当前页面弹出的窗口。
postMessage()方法接收两个参数:一条消息(一般是字符串,若需要传递非字符串,则用JSON.stringfy()将其转换为字符串,然后在onmessage事件处理程序中调用JSON.parse())和一个表示消息接收方来自哪个域的字符串。
接收到XDM消息时,会触发window对象的message事件,触发message事件后,传递给onmessage处理程序的事件对象包含三个重要属性:
data:作为 postMessage()第一个参数传入的字符串数据;
origin:发送消息的文档所在的域;
source:发送消息的文档的 window 对象的代理。这个代理对象主要用于在发送上一条消息的窗口中调用 postMessage()方法。如果发送消息的窗口来自同一个域,那这个对象就是window。source一般用来在< iframe >引入的页面中调用postMessage()方法向源窗口发送回执信息。
实例1:通过postMessage()向同域和不同域窗口发送数据
//send.html
<!DOCTYPE html>
<html>
<head>
<title>Html5 postMessage跨文档通信</title>
</head>
<body>
<input type="text" id="text">
<input type="button" id="send1" value="发送给localhost">
<input type="button" id="send2" value="发送给huan1">
<br/>
<br/>
<!--同一个域或者不同域都可以-->
<iframe id="ifr1" src="http://localhost:8080/Test/CSRF/accept.html"></iframe>
<iframe id="ifr2" src="http://www.huan1.com:8080/apachefile/accept.html"></iframe>
<script type="text/javascript">
var text = document.getElementById('text'),
send1 = document.getElementById('send1'),
send2 = document.getElementById('send2'),
// ifr = window.frames[0];
ifr1 = document.getElementById('ifr1').contentWindow;
//确保你使用的是iframe的contentWindow属性,而不是节点对象。
send1.addEventListener('click',function(){
//主窗口postMessage发送消息给iframe子窗口。
//子窗口通过监听message事件来获得消息
ifr1.postMessage(text.value,'http://localhost:8080');
});
ifr2 = document.getElementById('ifr2').contentWindow;
send2.addEventListener('click',function(){
//主窗口postMessage发送消息给iframe子窗口。
//子窗口通过监听message事件来获得消息
ifr2.postMessage(text.value,'http://www.huan1.com:8080');
})
</script>
</body>
</html>
//accept.html(放在同一个域下)
<!DOCTYPE html>
<html>
<head>
<title>localhost:8080</title>
</head>
<script type="text/javascript">
//在iframe窗口中监听messages事件,并接收消息
window.addEventListener('message',function(event){
var div1 = document.getElementById('div1');
if(event.origin === 'http://localhost:8080'){
div1.innerHTML += event.origin+":"+event.data +"<br>";
}
})
</script>
<body>
<div>
我是iframe:localhost:8080
<div id="div1"></div>
</div>
</body>
</html>
//accept.html(放在另一个域下)
<!DOCTYPE html>
<html>
<head>
<title>www.huan1.com:8080</title>
</head>
<script type="text/javascript">
//在iframe窗口中监听messages事件,并接收消息
window.addEventListener('message',function(event){
var div2 = document.getElementById('div2');
if(event.origin === 'http://localhost:8080'){
div2.innerHTML += event.origin+":"+event.data +"<br>";
}
})
</script>
<body>
<div>
我是iframe:www.huan1.com:8080
<div id="div2"></div>
</div>
</body>
</html>
结果: 点击按钮“发送给localhost”,文本内容发送给第一个窗口,点击“发送给huan1”,文本内容发送给了第二个窗口。其中,第一个窗口是和发送窗口同域,第二个是和发送窗口不同域。
实例2:不同域的两个窗口相互传递消息,double_trans1.html页面向double_trans2.html页面发送消息“你好”,double_trans2.html收到消息后显示出消息源域名和内容,并向源窗口发送自己的域名和“收到”。
//double_trans1.html
<!DOCTYPE html>
<html>
<head>
<title>Html5 postMessage跨文档通信</title>
</head>
<body>
<input type="text" id="text">
<input type="button" id="send" value="发送"><br/><br/>
<div>
localhost同源窗口
<div id="div2" style="border:solid 1px black;width:500px;height: 200px;"></div>
</div>
<br/>
<iframe id="ifr" src="http://www.huan1.com:8080/apachefile/double_trans2.html"></iframe>
<script type="text/javascript">
var text = document.getElementById('text'),
send = document.getElementById('send'),
div2=document.getElementById('div2'),
// ifr = window.frames[0];
ifr = document.getElementById('ifr').contentWindow;
window.addEventListener('message', function(ev){
if(ev.origin === 'http://www.huan1.com:8080'){
// alert('从'+ ev.origin + '传过来的消息:' + ev.data);
div2.innerHTML+=ev.data;
}
});
send.addEventListener('click',function(){
//主窗口postMessage发送消息给iframe子窗口。
//子窗口通过监听message事件来获得消息
ifr.postMessage(text.value,'http://www.huan1.com:8080');
})
</script>
</body>
</html>
//double_trans2.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<script type="text/javascript">
//在iframe窗口中监听messages事件,并接收消息
window.addEventListener('message',function(event){
var div1 = document.getElementById('div1');
if (event.origin === 'http://localhost:8080') {
div1.innerHTML += "来自窗口" + event.origin + ":"+event.data+"<br>";
}
//向主页面回送消息
event.source.postMessage(this.location+":收到", event.origin);
});
</script>
<body>
iframe:huan1
<div id="div1"></div>
</body>
</html>
结果: