【vue与iframe通讯】

vue 与 iframe 通讯

  • 发送数据
    • vue 向 iframe 发送数据
    • iframe 向 vue 发送数据
    • 接收信息( vue & iframe 通用)
  • 实现相互通讯
    • 通讯流程图
    • 实现代码
      • vue 页面
      • iframe页面
      • iframe 内部重定向访问地址,更新 vue 路由
  • 访问跨域
  • 代码下载

前言:vue嵌套iframe实现步骤

发送数据

vue 向 iframe 发送数据

	// utils/common.js/** vue向iframe发送数据* content iframe.contentWindow* type 事件类型* data 传送的数据*/export function sendPostMessage(content, type, data = {}) {content.postMessage({ type, data }, '*');}

iframe 向 vue 发送数据

 // update.html & base.html & includes.html ...function sendPostMessage(type, data = {}) {window.parent.postMessage({ type, data }, "*");}

接收信息( vue & iframe 通用)

实例化PubSub时, 入参需提前定义,不然接收不到消息

  // utils/iframe-message.js/*** 接收页面 postMessage 发送的信息* Pubsub提供多种类型供订阅,使用方法如下:* 1. 需要接收webSocket的地方,import eventsPub from '本文件路径'* 2. eventsPub.on(类型, callback)*    例:*      const receive = data => console.log('eventName', data)*      eventsPub.on('eventName', receive)* 3.不需要继续接收时调用*    eventsPub.remove("eventName", receive) 移除callback*//** 重要: postMessageEvent 中的 type 需提前定义 */class PubSub {list = {};constructor(events) {this.list = {};events.forEach(v => {this.list[v] = [];});}on(ev, callback) {if (this.list[ev]) {this.list[ev].push(callback);return true;} else {return false;}}emit(ev, data) {// data拷贝: 防止其他callback修改dataconst dataStr = JSON.stringify(data);if (this.list[ev]) {this.list[ev].forEach((v) => {try {v(JSON.parse(dataStr));} catch (err) {console.log("callback error:", err, v);}});return true;} else {return false;}}remove(ev, callback) {if (callback && this.list[ev]) {this.list[ev].forEach((v, i) => {if (v === callback) {this.list[ev].splice(i, 1);}});return true;} else {return false;}}}// 订阅的类型需要在postMessageEvent中提前定义好const postMessageEvent = ["PAGE_ISREADY"]const eventsPub = new PubSub(postMessageEvent);window.addEventListener("message", function (e) {if (e.data?.type) {eventsPub.emit(e.data.type, e.data.data)}});export default eventsPub;

实现相互通讯

通讯流程图

vue路由更新 及 iframe地址刷新时,两者之间的通讯流程
流程图

实现代码

vue 页面

  // IframeTemplate.vueimport { onMounted, onBeforeUnmount } from "vue";import eventsPub from "@utils/iframe-message.js"import { sendPostMessage } from "@utils/common.js"onMounted(() => {// 接收信息eventsPub.on("PAGE_ISREADY", pageIsReady)});onBeforeUnmount(() => {eventsPub.remove("PAGE_ISREADY", pageIsReady)});function pageIsReady() {// console.log("PAGE_ISREADY")updateIframeLoginInfo()}// 发送信息/** iframe 页面登录信息同步 */function updateIframeLoginInfo() {const iframeWindow = $("#common-iframe")[0].contentWindowsendPostMessage(iframeWindow, "LOGIN_INFO", {token: localStorage.getItem("TOKEN"),userInfo: localStorage.getItem("USER") || "{}"})}

iframe页面

	// utils/iframe-message.js// 将该文件写成原生写法: 删除 remove 之后的代码// 添加下边的代码/** 创建消息接收实例 */const postMessageEvent = ["LOGIN_INFO"]const eventsPub = new PubSub(postMessageEvent);/** 接收父页面的消息 */window.addEventListener("message", function (e) {if (e.data?.type) {eventsPub.emit(e.data.type, e.data.data)}});/** 发送消息 */function sendPostMessage(type, data = {}) {window.parent.postMessage({ type, data }, "*");}
  // base.html、includes.html、update.html...// 在所有的页面中引入iframe-message.js、jquery.js<script type="text/javascript" src="./js/jquery.js"></script><script type="text/javascript" src="./js/iframe-message.js"></script>// 并添加下边的代码<script type="text/javascript">/** 获取当前登录用户信息并存储 */function setUserInfo(data) {const { token, userInfo } = data;const curToken = localStorage.getItem("TOKEN")const curUser = localStorage.getItem("USER")curToken != token && localStorage.setItem("TOKEN", token)curUser != userInfo && localStorage.setItem("USER", userInfo)}$(document).ready(() => {// GET VUE MESSAGEeventsPub.on("LOGIN_INFO", setUserInfo)// NOTIFY VUE MESSAGEsendPostMessage("PAGE_ISREADY", { iframeIsReady: true })})</script>

iframe 内部重定向访问地址,更新 vue 路由

需将iframe的地址添加到vue路由上

  1. iframe页面判断是否是内部跳转,并将页面地址发送到vue

        // base.html...function setUserInfo(data) {// 其他...localStorage.setItem("FROM_PARENT", true)}$(document).ready(() => {// 其他.../** iframe内部页面跳转,加载完成 -  */const fromParent = localStorage.getItem("FROM_PARENT")localStorage.removeItem("FROM_PARENT")// 判断是否是vue 页面重定向的const { pathname, href, search } = window.locationlet path = pathname.split(".")[0];sendPostMessage("PAGE_ISREADY", !fromParent ? {} : { path })})```
  2. vue 接收到地址后,页面路由修改,但iframe页面不需要再刷新

        // IframeTemplate.vue// 监听路由变更watch(route, () => {const historyParams = history.state.params// 只更新路由时,iframe 页面地址不更新if (historyParams && historyParams.justRoute && isFrameSrcUpdate == route.path && !isMounted) {isFrameSrcUpdate = "";return;}// iframe 页面地址更新createIframe()});/** iframe 页面加载完毕* 1. 登陆信息同步* 2. iframe 内部跳转,页面地址变化后,vue route也修改(但页面不刷新)*/function pageIsReady(data) {updateIframeLoginInfo()if (data?.path) {let { path, name, query } = dataisFrameSrcUpdate = path;const exit = router.getRoutes().find(i => i.path == path)/** iframe 发送了一个未添加路由的页面*  1. 添加该页面路由,为能正常访问*  2. 在当前页面刷新后,会有路由不存在的问题,*    需在整体添加路由的位置将当前页面添加进进去*/!exit && router.addRoute({path,name,meta: { isIframe: true },component: () => import("../views/IframePage.vue")})// justRoute:只更新路由,不刷新页面router.push({ path, query, state: { params: { justRoute: true } } });}}
    

访问跨域

  • 问题:
    部署到环境上后,vue页面访问iframe地址会有访问跨域问题。
  • 解决方案:
    在部署vue 服务器配置时允许访问iframe的域名。
    如: Apache 部署vue 的服务器配置上添加一行配置:Header always append X-Frame-Options <iframe访问的域名>

代码下载

查看代码地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/842621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Pytorch框架的深度学习ShufflenetV2神经网络十七种猴子动物识别分类系统源码

第一步&#xff1a;准备数据 17种猴子动物数据&#xff1a; self.class_indict ["白头卷尾猴", "弥猴", "山魈", "松鼠猴", "叶猴", "银色绒猴", "印度乌叶猴", "疣猴", "侏绒"…

做抖音小店不懂这四个“重点”!那就别怪你的店铺,做不长久!

我相信大家做抖音小店&#xff0c;都去抖音刷过知识点&#xff0c;也去浏览器学习过技巧 但在这里&#xff0c;我给大家泼盆冷水 方法再多&#xff01;这四点不搞明白&#xff0c;那你的店铺出几天单&#xff0c;也就再也做不起来了 哪四点&#xff1f;请认真的看下去&#…

django-celery-beat自动调度异步任务

Celery是一个简单、灵活且可靠的分布式系统&#xff0c;专门用于处理大量消息的实时任务调度。它支持使用任务队列的方式在分布的机器、进程、线程上执行任务调度。Celery不仅支持异步任务&#xff08;如发送邮件、文件上传、图像处理等耗时操作&#xff09;&#xff0c;还支持…

2024.05.27学习记录

1、面经复习&#xff1a; 实际工作经验章节 2、代码随想录刷题&#xff1a;动态规划剩下部分和单调栈 3、rosebush 组件库完成Input 和 AutoComplete部分内容

2024甘肃省三支一扶报名流程详细图解

预计报名时间&#xff1a;2024年5月27日9:00至5月31日18&#xff1a;00 2024甘肃省三支一扶报名流程 登录甘肃人力人力资源考试中心&#xff0c;选择网上报名 进入账户登录&#xff0c;首次登录同学请先注册账号。 注册账号&#xff0c;认真填写&#xff0c;仔细核对信息。…

惠海 H6901B升压恒流3.7V 7.4V 12V 24V 30V 36V 48V 60V 80V 100V调光无频闪细腻顺滑

H6901B是一款升压型LED恒流驱动芯片&#xff0c;具有良好稳定性的特点。H6901B的主要特点包括宽输入电压范围&#xff08;2.7V-100V&#xff09;、高工作频率&#xff08;1MHz&#xff09;以及多种保护功能&#xff08;如芯片供电欠压保护、过温保护、软启动等&#xff09;。此…

美颜技术揭秘:美颜SDK与美颜接口的开发实践

一、美颜技术的基本原理 1.1面部检测与特征点识别 面部检测是美颜技术的第一步&#xff0c;通过计算机视觉算法检测图像中的人脸位置。常用的方法有Haar特征、卷积神经网络&#xff08;CNN&#xff09;等。 1.2图像增强与美化 -磨皮 -美白 -眼部增强 -脸型优化 1.3实时处…

【爬虫软件】2024最新短视频评论区抓取工具

一、背景说明 1.0 采集目标 采集DOU音评论数据对引流截流和获客有很多好处。首先&#xff0c;通过分析DOU音评论数据&#xff0c;我们可以更好地了解用户对于产品或内容的喜好和需求&#xff0c;从而调整营销策略&#xff0c;吸引更多用户关注和点击。其次&#xff0c;评论数据…

解密MySQL中的临时表:探究临时表的神奇用途

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 解密MySQL中的临时表&#xff1a;探究临时表的神奇用途 前言临时表的定义与分类创建与使用临时表临时表的操作与管理优化与性能提升注意事项与最佳实践 前言 在数据库管理中&#xff0c;临时表是一个…

PGP安装以及汉化

目录 1.安装 2.汉化 1.安装 (1&#xff09;进入setup目录&#xff0c;双击安装包开始安装 (2&#xff09;选择默认语言English (3&#xff09;接受安装协议 I accept the license agreement (4&#xff09;选择第二项 Do not display the Release Notes (5&#xff09;选择“…

第十四 Elasticsearch介绍和安装

docker-compose安装 kibana: image: docker.elastic.co/kibana/kibana:7.5.1 container_name: kibana ports: - "5601:5601" environment: ELASTICSEARCH_HOSTS: http://elasticsearch:9200 depends_on: - elasticsearch…

按尺寸筛选轮廓图中的轮廓

1.按短边筛选 原始轮廓图&#xff1a; import cv2 import numpy as np# 读取轮廓图 contour_image cv2.imread(..\\IMGS\\pp_edge.png, cv2.IMREAD_GRAYSCALE)# 使用cv2.findContours()函数获取所有轮廓 contours, _ cv2.findContours(contour_image, cv2.RETR_EXTERNAL, cv2…

学习Uni-app开发小程序Day17

今天开始&#xff0c;就把uni-app前期使用的全部学完了&#xff0c;现在就把以前学习的&#xff0c;做成一案例&#xff0c;中间有未讲的&#xff0c;在进行补充&#xff0c;这里是根据老师视频进行项目案例编写的。 先弄出效果图&#xff0c;然后在根据效果图进行代码的编辑 …

uni-app 微信 支付宝 小程序 使用 longpress 实现长按删除功能,非常简单 只需两步

1、先看效果 2、直接上代码 ui结构 <view class"bind" longpress"deleteImage" :data-index"index"><view class"bind_left">绑定设备</view><view class"bind_right"><view class"bind_t…

Raven2掠夺者2渡鸦2角色创建、游戏预下载、账号怎么注册教程

《渡鸦2》&#xff08;Raven 2&#xff09;是由韩国开发的一款大型多人在线角色扮演游戏&#xff08;MMORPG&#xff09;类型的手游&#xff0c;作为前作《Raven》的续集&#xff0c;继承并发展了其黑暗奇幻世界观&#xff0c;同时在游戏设计和内容上进行了大量创新。游戏预计于…

Spring:IoC容器(基于注解管理bean)

1. HelloWorld * 引入依赖* 开启组件扫描* 使用注解定义 Bean* 依赖注入 2.开启组件扫描 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/20…

阿里云OSS文件上传和下载完整指南

目录 前言 一、前期准备 二、文件上传 上传进度条 三、文件下载 1.流式下载 2.下载到本地 3.进度条 前言 文件上传是常见需求&#xff0c;一般我们不会把文件直接上传到应用服务器&#xff0c;因为单台服务器存储空间是有限的&#xff0c;不好扩展。阿里云对象存储&…

Diffusion Model 和 Stable Diffusion 详解

文章目录 Diffusion Model 基础生成模型DDPM概述向前扩散过程前向扩散的逐步过程前向扩散的整体过程 反向去噪过程网络结构训练和推理过程训练过程推理过程优化目标 详细数学推导数学基础向前扩散过程反向去噪过程 Stable Diffusion组成结构运行流程网络结构VAE 模型文本编码器…

MyBatis的基础操作

目录 一.什么是MyBatis? 二.使用MyBatis的准备工作 1.引入依赖: 2.配置数据库连接字符串(建立MaBatis和MySQL的连接) 3.在model包中建立数据库对应的实体类UserInfo 三.通过注解的方式实现MyBatis的开发 1.插入语句(Insert) 2.删除语句(Delete) 3.更新语句(Update) 4…

突破乙肝治疗瓶颈新希望!恒瑞医药小核酸疗法领跑进入II期临床试验

近日&#xff0c;恒瑞医药的针对慢性乙型肝炎的小核酸疗法要准备开启一项多中心、随机、开放、平行设计的 II 期研究,旨在评估 HRS-5635 注射液单独或与其他药物联合治疗慢性乙型肝炎患者的疗效和安全性二期临床实验。去年开启的1期&#xff0c;今年就要准备2期实验了。 咱们国…