HTML5提供了在网页文档之间相互接收与发送信息的功能。使用这个功能,只要获取到网页所在窗口对象的实例,不仅同源(域+端口号)的Web网页之间可以互相通信,甚至可以实现跨域通信。
首先,想要接受从其他的窗口那里发过来的消息,就必须对窗口对象的message
事件进行监视,代码如下所示:
1 2 3
| window.addEventListener('message', function() { ... }, false);
|
使用window
对象的postMessage
方法向其他窗口发送消息,该方法的定义如下
1
| otherWindow.postMessage(message, targetOrigin);
|
otherWindow为要发送窗口对象的引用,可以通过window.open
返回该对象,或通过对window.frames
数组指定序号或名字的方式来返回单个frame所属的窗口对象。
第一个参数为所发送的消息文本,或JSON转换后的文本。
第二个参数为接收消息的对象窗口的url地址。可以在url地址字符串中使用通配符“*”
指定全部地址,不过建议使用准确的url地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
<!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Parent</title> <style> div { margin: 10px; } </style> </head>
<body> <section> <h1>Parent Page</h1> <div id="msg"> Message Content </div> <div> <input id="text" type="text"> </div> <div> <button id="button" onclick="postMessage()">发送</button> </div> </section> <section> <h1>Child Page</h1> <iframe src="http://localhost:8111/html/child.html" width="100%" frameborder="0"></iframe> </section> <script> window.addEventListener('message', function (ev) { if (ev.origin != 'http://localhost:8111') { return; } document.getElementById('msg').innerHTML = ` 从${ev.origin}那里传过来的消息:${ev.data} ` }, false);
function postMessage() { var msg = document.getElementById('text').value; var iframe = window.frames[0]; iframe.postMessage(msg, 'http://localhost:8111/html/child.html'); } </script> </body>
</html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
<!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Child</title> <style> div { margin: 10px; } </style> </head>
<body> <div id="msg"> Message Content </div> <div> <input id="text" type="text"> </div> <div> <button id="button" onclick="postMessage()">发送</button> </div> <script> var source, origin;
window.addEventListener('message', function (ev) { if (ev.origin != 'http://localhost:8100') { return; } source = ev.source; origin = ev.origin; document.getElementById('msg').innerHTML = ` 从${ev.origin}那里来的消息:${ev.data} `; }, false);
function postMessage() { var msg = document.getElementById('text').value; if (source && origin) { source.postMessage(msg, origin); } } </script> </body>
</html>
|
本示例中的几个关键之处:
通过对window
对象的message
事件进行监听,可以接收消息。
通过访问message
事件的origin
属性,可以获取消息的发送源。
发送源与网站的url地址不是同一概念,发送源只包含域名和端口号,为了不接收从其他源恶意发送过来的消息,最好对发送源做个检查。
通过访问message
事件的data
属性,可以获取消息内容
使用postMessage
方法发送消息
通过访问message
事件的source
属性,可以获取消息发送源的窗口对象(准确的说,应该时窗口的代理对象)
通过这种方式,可以实现网页文档与网页文档之间、端口与端口之间、域与域之间互相传递消息。
参考文献
- 《HTML5与CSS3权威指南》