0
点赞
收藏
分享

微信扫一扫

#yyds干货盘点#iframe 通信:postMessage onmessage

​postMessage​​ 接口允许窗口之间相互通信,无论它们来自什么源。

因此,这是解决“同源”策略的方式之一。它允许来自于 ​​marh.com​​ 的窗口与来自于 ​​qq.com​​ 的窗口进行通信,并交换信息,但前提是它们双方必须均同意并调用相应的 JavaScript 函数。这可以保护用户的安全。

这个接口有两个部分。

1 postMessage

想要发送消息的窗口需要调用接收窗口的 ​​postMessage​​ 方法。换句话说,如果我们想把消息发送给 ​​win​​,我们应该调用 ​​win.postMessage(data, targetOrigin)​​。

参数

​data​

要发送的数据。可以是任何对象,数据会被通过使用“结构化序列化算法(structured serialization algorithm)”进行克隆。IE 浏览器只支持字符串,因此我们需要对复杂的对象调用 ​​JSON.stringify​​ 方法进行处理,以支持该浏览器。

​targetOrigin​

指定目标窗口的源,以便只有来自给定的源的窗口才能获得该消息。

// <iframe src="http://127.0.0.1:8080/2.html" name="example" />  
 
 let win = window.frames.example;    
 win.postMessage("message", "http://127.0.0.1:8080");

2 onmessage

为了接收消息,目标窗口应该在 ​​message​​​ 事件上有一个处理程序。当 ​​postMessage​​​ 被调用时触发该事件(并且 ​​targetOrigin​​ 检查成功)。

event 对象具有特殊属性:

  • ​data​​ 从 postMessage 传递来的数据。
  • ​origin​​ 发送方的源,例如 http://javascript.info
  • ​source​​ 对发送方窗口的引用。如果我们想,我们可以立即 source.postMessage(...) 回去。

要为 ​​message​​ 事件分配处理程序,我们应该使用 ​​addEventListener​​,简短的语法 ​​window.onmessage​​ 不起作用。

 window.addEventListener("message", function(event) {
   console.log(event)
   if (event.origin != 'http://http://127.0.0.1:8080') {
     // 来自未知的源的内容,我们忽略它
     return;
  }
 
   if (window == event.source) {
     // chrome 下, 页面初次加载后会触发一次 message 事件, event.source 是 window 对象
// 此时 event.source.postMessage 会形成死循环
     // 因此,要跳过第一次的初始化触发的情况
     return
  }
 
   console.log( "received: " + event.data );
 
   // 可以使用 event.source.postMessage(...) 向回发送消息
   event.source.postMessage('i am 2.html')
 }, source);

举报

相关推荐

0 条评论