• 页面间通信postMessage和onmessage


    前言

    postMessageonmessage是HTML5的方法,用来解决跨页面通信,或者通过iframe嵌套的不同页面的通信的。
    postMessage为发送方,onmessage为接收方。

    用法

    otherWindow.postMessage(message, targetOrigin, [transfer])
    
    • 1

    otherWindow是其他窗口的window对象。可以通过以下几种方法获得,例如window.open()返回的窗口对象、window.parent来获取当前父窗口的window对象 或者 iframe元素的contentWindow属性等等。

    参数

    message:要发送到另一个窗口的数据
    targetOrigin:指定此窗口的来源必须是要分派的事件,可以是文字字符串"*"(表示无首选项)或 URI。
    transfer(可选):是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

    window.addEventListener('message', (event) => {})
    
    • 1

    event属性

    data:从另一个窗口传递的对象
    origin:调用 postMessage 时消息发送方窗口的 origin ,通过event.origin获取。要注意的是,当你的页面使用非服务器环境时这个属性值为null,在本地进行测试时请注意这一点,因为你可能拿不到origin的值。此属性用来判断发送方的身份,防止恶意的第三方向页面发送恶意消息进行攻击。 典型来源的示例:https://example.org
    source:调用 postMessage 时消息发送方window对象的引用

    使用场景

    页面与嵌套的 iframe 消息传递

    // 父页面
    <iframe id="iframe" src="demo.html" frameborder="2" width="100" height="100"></iframe>
    
    <script>
      // 向iframe发送消息
      const iframe = document.querySelector('#iframe');
      iframe.onload = function() {
        iframe.contentWindow.postMessage('我是父页面的数据', '*');
      }
      window.addEventListener('message', (e) => {
        console.log('e', e.data); // 我是iframe数据
      })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    // demo.html
    <script>
      window.addEventListener('message', (e)=> {
        console.log('e', e.data) // 我是父页面的数据
        // 向父页面发送数据
        window.parent.postMessage('我是iframe数据', '*') // 也可以写成 e.source.postMessage('我是iframe数据', '*')
      }, false);
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    安全问题

    如果不希望收到来自其他站点的消息,不要为message事件添加任何事件监听,否则请始终使用originsource属性验证发件人的身份。

    window.addEventListener("message", (event)=>{
       var origin = event.origin;
       if (origin !== "http://example.org:8080")
         return;
       // ...
    }, false);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    中级前端面试整理-上篇
    Cesium 空间量算——生成点位坐标
    一个基本的BERT模型框架
    6.8完全二叉树的节点个数(LC222-E)
    Unity导出Android studio项目遇到的aar无法打包问题
    Kettle 裁剪表详解
    【ES6】-- common.js与ES6模块化的差异
    嵌入式行业入行6年的一点小感想
    (二) MdbCluster分布式内存数据库——分布式架构
    从javascript到vue再到react的演变
  • 原文地址:https://blog.csdn.net/m0_51328823/article/details/127849353