跨域(五)——postMessage
HTML5的postMessage机制是客户端最直接的中档传输方法,一般用在iframe中父页与子页之间的客户端跨域通信。
浏览器支持情况:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 。 Facebook已经使用了这个功能,用postMessage支持基于web的实时消息传递。
用法:otherWindow.postMessage(message, targetOrigin)
otherWindow: 对接收信息页面的window的引用。可以是页面中iframe的contentWindow属性;window.open的返回值;通过name或下标从window.frames取到的值。
message: 所要发送的数据,string类型。
targetOrigin: 用于限制otherWindow,“*”表示不作限制
下面是一个基于postMessage的简单聊天实例:
http://www.evil.com:8081/langtao/evil.html页面代码:
<iframe id="ifr" src="http://www.foo.com:8081/langtao/foo.html" width="500" height="300"></iframe> <div id="msgbox"> </div> <input type="text" id="msg" /> <input type="button" value="发送" id="btn"/> <script type="text/javascript"> window.onload = function() { document.getElementById('btn').onclick=function(){ var ifr = document.getElementById('ifr'); var targetOrigin = 'http://www.foo.com:8081/langtao/'; // 若写成http://www.foo.com:8081/langtao/foo.html'效果一样 var msg=document.getElementById('msg').value; ifr.contentWindow.postMessage(msg,targetOrigin); var c=document.createElement('div'); c.innerHTML="你说:"+msg; msgbox.appendChild(c); } }; window.addEventListener('message', function(e){ // 通过origin属性判断消息来源地址 if (e.origin == 'http://www.foo.com:8081') {//不可以设置为'http://www.foo.com:8081/' var c=document.createElement('div'); c.innerHTML="来自"+e.origin+"的消息:"+e.data; msgbox.appendChild(c); } }, false); </script>
http://www.foo.com:8081/langtao/foo.html页面代码:
<div id="msgbox"> </div> <input type="text" id="msg" /> <input type="button" value="发送" id="btn"/> <script type="text/javascript"> var msgbox=document.getElementById('msgbox'); window.addEventListener('message', function(e){ if (e.origin == 'http://www.evil.com:8081') { var c=document.createElement('div'); c.innerHTML="来自"+e.origin+"的消息:"+e.data; msgbox.appendChild(c); } }, false); document.getElementById('btn').onclick=function(){ var targetOrigin = 'http://www.evil.com:8081/langtao/'; var msg=document.getElementById('msg').value; window.top.postMessage(msg, targetOrigin); var c=document.createElement('div'); c.innerHTML="你说:"+msg; msgbox.appendChild(c); } </script>
效果图:
从代码中可以看到,postMessage机制,这种跨域需要双方默契配合,且可以在客户端通过orgin进行判断请求的来源是否合法。