Js实现2个浏览器窗口数据交互window.postMessage()方法

一、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.org/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.org/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.org(意味着端口为443),http://example.net(意味着端口为80)和http://example.com:8080。请注意,此来源不保证是该窗口的当前或未来来源,该窗口可能已被导航到调用postMessage后的其他位置。
source
对发送消息的window对象的引用;你可以使用它来建立两个不同来源的窗口之间的双向通信。

注意

任何窗口可以在任何其他窗口访问此方法,在任何时间,无论文档在窗口中的位置,向其发送消息。 因此,用于接收消息的任何事件监听器必须首先使用origin和source属性来检查消息的发送者的身份。 这不能低估:无法检查origin和source属性会导致跨站点脚本攻击。

与任何异步调度的脚本(超时,用户生成的事件)一样,postMessage的调用者不可能检测到侦听由postMessage发送的事件的事件处理程序何时抛出异常。

分派事件的origin属性的值不受调用窗口中document.domain的当前值的影响。

仅对于IDN主机名,origin属性的值不是始终为Unicode或punycode; 在使用此属性时,如果您期望来自IDN网站的消息,则最大程度地兼容性检查IDN和punycode值。 这个值最终将始终是IDN,但现在你应该同时处理IDN和punycode表单。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值