原文链接 http://www.bujiaban.net/wordpress/?p=186
W3C 规范http://www.w3.org/TR/html5/comms.html
本文DEMO
(一)跨源通信
协议,主机,端口。
http://www.bujiaban.net/a.html与
http://www.bujiaban.net/html/geolocation.html的源是一样的,因为不考虑路径
方式
跨文档通信cross-document messaging
信道通信channel messaging
XMLHttpRequert
交互
浏览器前端(ifrmae,标签页,浏览器窗口之间)(cross-document messaging,channel messaging)
与后端服务通信(XMLHttpRequert)
消息
以消息事件方式实现。适用server-sent events, Web sockets, cross-document messaging, and channel messaging
消息定义如下
(二)cross-document messaging
API
window . postMessage(message, [ ports, ] targetOrigin)
message:要发送的消息
targetorigin:目标页面
发送消息
调用目标页面的postMessage
如iframe的contentWindow
document.getElementById("innerFrame").contentWindow.postMessage("abc","http://www.bujiaban.net/b.html");
接受消息
监听window的message事件
接收到的事件对象中比较重要的属性是:
event . data :发送方发送过来的消息
event . origin:消息来源。从安全性出发,该字段由浏览器来设置,
发送方不能更改,接收方根据该字段判断消息是否合法。
示例代码http://www.bujiaban.net/a.html
(三) 信道通信
创建双工信道
var channel = new MessageChannel();
信道含有端口数组,含有两个port,每一个port都可以发送与接收,一般port1用于本地接收
port2用于远端发送
与其他页面建立信道,例如
document.getElementById("innerFrame").contentWindow.postMessage("hello",[channel.port2],
"http://blog.bujiaban.net/MessageChannelB.html"); 注意,在IE10参数顺序可能不一样[channel.port2]
在最后,如postMessage("hello","http://blog.bujiaban.net/MessageChannelB.html",[channel.port2]);
接收信道消息
postMessage与onmessage组合使用
先收到postMessage过来的消息,消息里面的ports[0]就是建立好的信道,可以保存下来继续使用,可以用来发送数据,
也可以设置onmessage函数来接收信道消息,如
if( window.attachEvent )
window.attachEvent("onmessage",rMessage)
else
window.addEventListener("message",rMessage,false);
var A_port;
function rMessage(e)
{
alert(e.data);
A_port=e.ports[0];
e.ports[0].onmessage=function(data){alert(data.data+"port message");A_port.postMessage(data.data+" back");};
e.ports[0].postMessage(e.data+" back");
}//fun
示例代码http://www.bujiaban.net/MessageChannel.html
http://www.bujiaban.net/MessageChannel.html 的代码
<!DOCTYPE html>
<html>
<head>
<title>MessageChannel 信道消息传递</title>
</head>
<body onload="load()">
<iframe id="innerFrame" src="http://blog.bujiaban.net/MessageChannelB.html">
</iframe>
<script type="text/javascript">
function load()
{
var i=0;
var channel = new MessageChannel();//创建信道
channel.port1.onmessage = function (event) {
// Message is in event.data
alert("Channel Message is: " + event.data);
if( i++ < 1 )
channel.port1.postMessage("i");
}
//先建立信道
document.getElementById("innerFrame").contentWindow.postMessage("hello",[channel.port2],"http://blog.bujiaban.net/MessageChannelB.html");
channel.port1.postMessage("j");
}
</script>
</body>
</html>
http://blog.bujiaban.net/MessageChannelB.html代码
<!DOCTYPE html>
<html>
<head>
<title>ChannelMessage 跨源消息传递(接收)</title>
</head>
<body>
<div>abc</div>
<script type="text/javascript">
if( window.attachEvent )
window.attachEvent("onmessage",rMessage)
else
window.addEventListener("message",rMessage,false);
var A_port;
function rMessage(e)
{
alert("postMessage is:"+e.data);
A_port=e.ports[0];//保存到变量,下次使用
e.ports[0].onmessage=function(data){alert("Channel Message is: "+data.data);A_port.postMessage(data.data+" back");};
e.ports[0].postMessage((e.data+" back");
}//fun
</script>
</body></html>
