当前位置: 首页 > article >正文

Vue前端页面内嵌套本项目iframe窗口的通信传输方式

一、目的

想要在iframe中使用本项目页面、并能够与其父页面组件实现实时通信。Vue前端页面内嵌套本项目iframe窗口的通信传输方式-星林社区
https://www.jl1mall.com/forum/PostDetail?postId=20241202172800023969

二、iframe通信方式

 

1.接收消息

页面需要监听 message 事件。在消息的接收方页面内添加window.addEventListener("message",receiveMessage,false);

receiveMessage是接收到消息后对消息的解析、存储、处理函数。我们可以按照实际需求自行定义函数名称以及其中的数据处理过程。

2.消息发送

  • 父页面给iframe子页面发送消息

为iframe子页面定义name值,在发送消息函数中通过 window.frames[name];获取名为name的iframe窗口,向这个iframe窗口对象中采用postMessage的方法发送消息。注意:通过window.frames获取的每个子窗口都是一个 window 对象,而不是 iframe DOM 元素。

  • iframe子页面给父页面发送消息

通过window.parent获取父页面对象发送消息 window.parent.postMessage(msg, '*');

三、传输数据格式

当参数是复杂对象时,我们还需要对数据处理后再传输。因为在 Web Workers 的上下文中, postMessage 方法用于在主线程和工作线程之间传递数据。由于 Web Workers 运行在不同的全局上下文中,所以传递给 postMessage 的数据必须能够被 结构化克隆算法 处理。这通常意味着你只能发送基本的数据类型(如字符串、数字、布尔值、null、undefined、ArrayBuffer、Blob、ImageBitmap、ImageData、File 和 FileList 等)或者可以序列化为这些类型的对象。

常见的不能发送的对象包括函数、DOM 节点、XMLHttpRequest 对象或者其它具有复杂内部状态的对象。如果你尝试发送这样的对象,你就会遇到 “Uncaught DataCloneError: Failed to execute 'postMessage' on 'Window': [object Object] could not be cloned.” 的错误。

遇见这一报错时我们可以采用JSON.stringify(data)对data数据进行处理。

四、方法实践

1.父页面

在父页面中添加iframe窗口:

<iframe
    :src="url"
    width="100%"
    height="100%"
    scrolling="yes"
    frameborder="0"
    @load="loadFrame"
    id="frame_box"
    name="myiframe"
    >
</iframe>

消息发送与接收:

// 给iframe传递数据
function sendMessage(msg){
    let iframeWin = window.frames["myiframe"];
    //将iframe的window窗体存储至data对象中会出现跨域报错
    iframeWin.postMessage(msg,"*");
}
//监听iframe子页面消息
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);
   let dataMessage = JSON.parse(e.data);
}

2.子页面

window.addEventListener("message",receiveMessage,false);
function receiveMessage(event){
    let data = event.data
    let dataConfig = JSON.parse(data)
    console.log('我是父页面传递过来的', dataConfig)
    if(data.type == 'theme'){
      themeStore.globalThemeClass=data.value
    }
}
//向父元素发送消息,messageSelect的格式是根据项目需求自定义的,可以是字符串,若是字符串,下方无需进行JSON处理
function isSelect(index){
    selectIndex.value = index
    const messageSelect = {
        type:'chartSelect',
        value:index
    }
    let msg = JSON.stringify(messageSelect)
    window.parent.postMessage(msg, '*');
}

五、iframe加载

onload 事件在frame或者iframe载入完成后被触发。我们可以通过onload事件进行初始数据的传输。

function loadFrame() {
    // 获取iframe节点
    iframeLoading.value = true
    const iframeBox = document.getElementById('frame_box')
    const currentDoc = iframeBox.contentDocument || iframeBox.contentWindow.document; // 非同源会在contentWindow.document报错
    // 获取iframe html文件
    const baseWidth = 1920;
    const baseFontsize = 10;
    const doc = iframeBox.contentWindow.document
    const screenWidth = doc.documentElement.clientWidth;
    const scale= screenWidth / baseWidth;
    const htmlElement = currentDoc.getElementsByTagName("html")[0];
    htmlElement.style.fontSize =`${baseFontsize* Math.min(scale,2)}px`;// 设置最大缩放比例为2倍,可根据需求调整
        let messageConfig = {
            type:'chart',
            value:chartConfigData.value
        }
        let msg = JSON.stringify(messageConfig)
        //将iframe的window窗体存储至data对象中会出现跨域报错
        //由于切换url postMessage传递数据需要时间
        setTimeout(()=>{
            let iframeWin = window.frames["myiframe"];
            iframeWin.postMessage(msg,"*");
            //定时器的值如何设置最优有待商榷
        },1600)
}


http://www.kler.cn/a/421391.html

相关文章:

  • 【深度学习|特征增强融合模块】MAF (Multi-scale Attention Fusion)一种多尺度的注意力融合模块
  • 原型模式的理解和实践
  • 小迪安全第四十二天笔记 简单的mysql注入 mysql的基础知识 用户管理数据库模式 mysql 写入与读取 跨库查询
  • 《从0到1常用Map集合核心摘要 + 不深不浅底层核心》
  • 网络安全内容整理二
  • Java基础面试题12:Java中的两种异常类型是什么?它们有什么区别?
  • AttributeError: ‘DataFrame‘ object has no attribute ‘append‘的参考解决方法
  • Linux67 绑定网卡【bonding和team】
  • 技术速递|Java on Azure Tooling 10月更新 - Azure 函数托管身份支持,Java on Azure 工具指南推出
  • Swift 宏(Macro)入门趣谈(五)
  • 【Anaconda】Anaconda3 下载与安装教程(Ubuntu 22.04)
  • SQL语法——DDL
  • 一键生成后端服务,MemFire Cloud重新定义开发效率
  • 基于Matlab SEIR模型的传染病传播分析与防控策略模拟
  • Leetcode 每日一题 205.同构字符串
  • 114. UE5 GAS RPG 实现配置怪物生成
  • 量化交易系统开发-实时行情自动化交易-8.7.文华平台
  • 【开源】A060-基于Spring Boot的游戏交易系统的设计与实现
  • 从0开始学PHP面向对象内容之常用设计模式(中介,访问)
  • 晶圆制程setup的一些探讨