iframe跨域消息通信(postMessage和message事件)

一、文章参考

  1. IFrame消息传递
  2. 使用 iframe + postMessage 实现跨域通信

二、知识点

  1. 页面需要监听 message 事件,window.addEventListener(“message”, dealMessage, false);

  2. 父页面向子iframe页面发送消息:

document.getElementById("mapIframe").contentWindow.postMessage("父页面向子页面发送消息", "*");
或者
document.getElementById("mapIframe").contentWindow.postMessage("父页面给子页面发送信息", "http://10.192.195.166:56225/son.html");

  1. 子iframe页面向父页面发送消息:

window.parent.postMessage('子页面向父页面发送消息','*');

三、例子说明

  1. 父页面
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div>我是父亲页面</div>
    <button onclick="parentMsgToSon()">父页面给子页面发送信息</button>
    <!-- <iframe
      id="mapIframe"
      src="http://127.0.0.1:9999/son.html"
      style="width: 500px; height: 500px"
    ></iframe> -->
    <iframe
      id="mapIframe"
      src="http://10.192.195.166:54473/son.html"
      style="width: 500px; height: 500px"
    ></iframe>
  </body>
  <script>
    // 父页面向子页面发送消息
    function parentMsgToSon() {
      document.getElementById("mapIframe").contentWindow.postMessage("父页面向子页面发送消息", "*");
    }
    // 监听子页面的消息
    if (typeof window.addEventListener != "undefined") {
      // for ie9+、chrome
      window.addEventListener("message", dealMessage, false);
    } else if (typeof window.attachEvent != "undefined") {
      // for ie8-
      window.attachEvent("onmessage", dealMessage);
    }
    // 处理消息的回调函数
    function dealMessage(e) {
      console.log(e.data);
    }
  </script>
</html>
  1. 子页面
<!DOCTYPE html>
<html lang="en">
<body>
  <div>我是子页面</div>
  <button onclick="sendMsgToParent()">子页面给父页面发送信息</button>
</body>
<script>
  // 向iframe父页面发送消息
  function sendMsgToParent() {
    window.parent.postMessage('子页面向父页面发送消息', '*');
  }
  // 监听消息
  if (typeof window.addEventListener != 'undefined') {      // for ie9+、chrome
    window.addEventListener('message', dealMessage, false);
  } else if (typeof window.attachEvent != 'undefined') {   // for ie8-
    window.attachEvent('onmessage', dealMessage);
  }
  // 监听消息的回调函数
  function dealMessage(e) {
    console.log(e.data);
  }
</script>
</html>

3.1 能不能使用非message事件?

不能,否则起不到效果

四、通信的前提是iframe 加载完成

4.1 问题描述

在工作中,由于iframe的地址src 是变动的,于是,自己在写代码的时候,iframe一旦变化之后就立马向iframe发送消息,一直到不到预期的效果,但是技术路线好像又没有问题,经过反复调试和代码审查发现,是由于iframe 里面的代码还没有加载完成就发送消息,导致iframe 子页面没有处理消息信息的逻辑

4.2 解决办法,iframe 添加 onload 事件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <button onclick="test()">改变</button>
  <iframe id="aaa" src="https://www.baidu.com" onload="iframeLoad()"></iframe>
</body>
</html>
<script>
console.log('start')
function iframeLoad () {
  console.log('load')
  alert('页面加载完成')
}
console.log('end')

function test () {
  document.getElementById('aaa').src = 'http://hui.dev.hikhub.net/zh/form/input.html#%E5%A4%8D%E5%90%88%E5%9E%8B%E8%BE%93%E5%85%A5%E6%A1%86'
}
</script>
  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在 Web 开发中,当网页中包含来自不同域名的 iframe(内嵌框架)时,由于浏览器的同源策略限制,iframe 之间的直接通信会受到限制。为了实现 iframe 之间的跨域通信,可以使用 postMessage 方法。 postMessage 是一种 HTML5 提供的跨文档消息传递机制,它允许在不同窗口或 iframe 之间发送消息。通过 postMessage,可以在不同域名之间进行安全的双向通信。 使用 postMessage 进行跨域通信的步骤如下: 1. 在发送消息的页面(发送方)中,使用 JavaScript 调用 postMessage 方法发送消息。该方法接受两个参数:要发送的消息和接收消息的目标窗口的源(origin)。目标窗口的源可以是具体的域名、协议和端口号,或者是通配符 "*" 表示任意源。 ```javascript var targetWindow = document.getElementById('target-frame').contentWindow; targetWindow.postMessage('Hello', 'https://target-domain.com'); ``` 2. 在接收消息的页面(接收方)中,监听 message 事件,通过 event.data 获取接收到的消息。在事件处理程序中可以对消息进行处理。 ```javascript window.addEventListener('message', function(event) { if (event.origin === 'https://source-domain.com') { console.log('Received message: ' + event.data); } }); ``` 通过这种方式,发送方和接收方可以进行跨域通信,并且可以在消息中传递复杂的数据结构。但要注意,为了确保安全性,应该在接收方对来自不同源的消息进行验证,以防止恶意代码的攻击。 需要注意的是,postMessage 方法只能在现代浏览器中使用,兼容性可能会有所差异。此外,在使用 postMessage 进行跨域通信时,也需要确保目标窗口(接收方)支持 postMessage 方法。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值