一、window.postMessage是什么?
根据官方给定的理解如下:
window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。
从广义上讲,一个窗口可以获得对另一个窗口的引用(比如 targetWindow = window.opener),然后在窗口上调用 targetWindow.postMessage() 方法分发一个 MessageEvent 消息。接收消息的窗口可以根据需要自由处理此事件。传递给 window.postMessage() 的参数(比如 message )将通过消息事件对象暴露给接收消息的窗口。
二、示例
A.html父窗口代码如下:
<!DOCTYPE html>
<html xmlns="http://www.w3/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
</head>
<body>
<h1>父窗口页面</h1><br /><button onclick="btnOpen()">打开子窗口</button>
<script>
function btnOpen() {
var domain = 'http://127.0.0.1:5500/'; // 这里替换成自己的域名
var strWindowFeatures = "width=600,height=600,menubar=yes,location=yes,resizable=yes,scrollbars=true,status=true,left=200,top=100";
var myWindow = window.open(domain + 'B.html', 'testWindow', strWindowFeatures);
//周期性的发送消息
setInterval(function () {
var message = '当前时间为: ' + (new Date().getTime());
console.log('开始传输: ' + message);
//send the message and target URI
myWindow.postMessage(message, '*');
}, 1000);
//监听消息反馈
window.addEventListener('message', function (event) {
if (event.origin !== 'http://127.0.0.1:5500') return; //验证是不是当前域发送的
console.log('接收成功: ' + event.data);
}, false);
}
</script>
</body>
</html>
B.html页面代码如下:
<!DOCTYPE html>
<html xmlns="http://www.w3/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
</head>
<body>
<h1>子窗口页面</h1><br /><button onclick="begin()">开始监听</button>
<script>
function begin() {
window.addEventListener('message', function (event) {
if (event.origin !== 'http://127.0.0.1:5500') return; //验证是否为当前域 保证安全
console.log("接收父窗口数据:" + event.data);
event.source.postMessage('你好,父窗口', event.origin);
}, false);
}
</script>
</body>
</html>
调度消息(event)的属性是:
data
从另一个窗口传递的对象。
origin
调用当时发送消息的窗口的原点postMessage。此字符串是协议和“://”的串联,如果存在,则为主机名,如果存在端口,则“:”后跟端口号,并且与给定协议的默认端口不同。典型起源的例子是https://example(意味着端口为443),http://example(意味着端口为80)和http://example:8080。请注意,此来源不保证是该窗口的当前或未来来源,该窗口可能已被导航到调用postMessage后的其他位置。
source
对发送消息的window对象的引用;你可以使用它来建立两个不同来源的窗口之间的双向通信。
注意
任何窗口可以在任何其他窗口访问此方法,在任何时间,无论文档在窗口中的位置,向其发送消息。 因此,用于接收消息的任何事件监听器必须首先使用origin和source属性来检查消息的发送者的身份。 这不能低估:无法检查origin和source属性会导致跨站点脚本攻击。
与任何异步调度的脚本(超时,用户生成的事件)一样,postMessage的调用者不可能检测到侦听由postMessage发送的事件的事件处理程序何时抛出异常。
分派事件的origin属性的值不受调用窗口中document.domain的当前值的影响。
仅对于IDN主机名,origin属性的值不是始终为Unicode或punycode; 在使用此属性时,如果您期望来自IDN网站的消息,则最大程度地兼容性检查IDN和punycode值。 这个值最终将始终是IDN,但现在你应该同时处理IDN和punycode表单。
更多推荐
Js实现2个浏览器窗口数据交互window.postMessage()方法
发布评论