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

关于iframe一些通讯的记录(可适用工作流审批)

一.知识点

(1).我们可以通过postMessage(发送方)和onmessage(接收方)这两个HTML5的方法, 来解决跨页面通信问题,或者通过iframe嵌套的不同页面之间的通信

a.父页面代码如下

<div v-if="src" class="iframe"><iframeref="iframe"id="iframe"width="100%"height="600"loading="lazy":src="src"frameborder="0"scrolling="no"marginheight="0"marginwidth="0"@load="loaded"></iframe>
</div>

a1.父页面向子页面发送信息(两种方法)

第一种

const iframe = document.getElementId('iframe')//id
//第一个参数是发送的消息,无格式要求;第二个参数是域名限制,当不限制域名时填写*
// 后面的 * 号就是处理跨域问题的,任何域名都不会出现跨域问题
// 传递的参数可以是数组,对象,字符串等 
iframe.contentWindow.postMessage('你需要传的数据', "*"); //数据比如({},'*'),('123','*')
// 也可以指定传送域名地址,这个域名不会出现跨域问题,写父页面(接收)域名地址
iframe.contentWindow.postMessage("需要传递的参数", 'http://0.0.0.0:8080')

第二种

this.$refs.iframe.contentWindow.postMessage(workDetailsData.workflowList,'*')

a2.子页面接收父页面收到的信息

 * 函数防抖* @param fn* @param interval* @returns {Function}* @constructor*/
export const Debounce = (fn, t) => {let delay = t || 500let timerreturn function () {let args = argumentsif (timer) {clearTimeout(timer)}timer = setTimeout(() => {timer = nullfn.apply(this, args)}, delay)}
}import { Debounce } from '@/utils/public.js'
mounted() {window.onmessage = this.handleMesg// addEventListener触发多次问题// window.addEventListener('message', this.handleMesg)}
},//防抖处理
handleMesg: Debounce(function (e) {//这里做接收数据的操作if(e){console.log(e.data)
}}),

a.3子页面(iframe加载的页面)向父页面传递消息

window.parent.postMessage({string: '我是iframe里面的数据'}, "*");

a.4父页面接收子页面传递的消息

window.onmessage = function(event){console.log(event.data.string) //我是iframe里面的数据
}

a.5 父页面接收子页面传递的消息(第二种)

//监听单个事件
window.addEventListener('message', function (msg) {console.log(msg.data.string)
})

二.项目实践

1.效果图

编辑

编辑

编辑

逻辑如下

1.首先点击审批通过按钮,调用方法

<el-buttonv-if="hasApproved"type="primary"size="small"@click="submit('Approved')">审批通过
</el-button>

2.方法如下

// 审批submit(data) {this.operateStatus = data //传过来的状态储存起来if (this.suspended) { //默认是false  请求详情接口时会根据后端返回这个字段判断他是否挂起this.$message.error('该任务已挂起,无法进行操作!')return}if (data === '撤回') {this.confirmSubmit()return}let label = data === 'Approved' ? '审批通过' : '审批拒绝'this.assignee_schema_model.comment =data === 'Approved' ? '批准' : '拒绝'this.dialogTitle = `确认是否${label}`this.msgContent = `确认${label}吗?`this.visible = true //打开弹窗},
弹窗如下

3.点击确定调用接口方法,调用接口时进行一些判断操作如下

  confirmSubmit() {let data = this.operateStatusthis.isLoading = trueif (data === 'Approved' || data == 'Rejected') {const params = { //审批流接口需要的参数variables: [{name: 'approveResult',value: data === 'Approved' ? 'Approved' : 'Rejected', //判断是同意还是拒绝},{name: 'comment',value: this.assignee_schema_model.comment,},{name: 'isWithdraw',value: '0',},],action: 'complete',comment: this.assignee_schema_model.comment,currentTaskId: this.$route.query.id,}if (!this.assignee_schema_model.comment) { //判断是否写了批注 不能为空this.$message.error('请输入批注!')this.isLoading = falsereturn}//重点 这里假如你是需要在自己的页面,比如商品详情页面,即iframe的页面自己调用自己中心的后端接口,不通过公共的审批接口时,需要进入这里,this.isPostMsg这个数据需要自己判断是否需要进入if (this.isPostMsg && data == 'Approved') {// 审批动作在iframe页面中完成this.$refs.iframe.contentWindow.postMessage( //向iframe 页面传递信息{status: data,value: this.assignee_schema_model.comment,params: params,},'*')this.visible = falsethis.isLoading = falsewindow.addEventListener('message', this.handleMesg) //接收iframe页面传递过来的信息return //不往下执行 即不调用公共审批接口}if (!this.src) { //判断配置console.log('审批流配置问题,formKey为空')this.$message.error('流程配置问题,/activiti/task接口返回的formKey为空')this.visible = falsethis.isLoading = falsereturn}if (!this.isOpenIframe(this.src)) {//没有被审批流程的菜单权限this.$message.error(this.authMenuMsg)this.visible = falsethis.isLoading = falsereturn}taskAction(params) //调用公共审批接口 (包含了同意和拒绝) 根据定义的参数判断.then((res) => {if (res.failed === true) {this.$message.error(res.message || '操作失败,请联系管理员')this.isLoading = false} else {this.$message.success('操作成功')this.visible = falsethis.isLoading = falsethis.$store.dispatch( //关闭当前页面路由'tabsBar/delVisitedRoute',this.$route.fullPath)this.$router.push(`/tcl/tof/message/workflow/wait-list`) //跳转到待办列表页面}}).catch((error) => {this.$message.error(error)this.isLoading = false})} else {// 撤回backAction(this.$route.query.id) //撤回流程公共 接口.then((res) => {if (res.failed === true) {this.$message.error(res.message || '操作失败,请联系管理员')this.isLoading = false} else {this.$message.success('操作成功')this.$store.dispatch('tabsBar/delVisitedRoute',this.$route.fullPath)// this.$router.go(-1)this.visible = falsethis.isLoading = falsethis.$router.push(`/tcl/tof/message/workflow/wait-list`)}}).catch((error) => {this.$message.error(error)this.isLoading = false})}},

4.父页面的handleMesg方法(重点交互)

//防抖 (debounce): 将多次高频操作优化为只在最后一次执行,通常使用的场景是:用户输入,只需再输入完成后做一次输入校验即可。
//防抖处理 高频调用handleMesg: Debounce(function (e) {if (e.data.type == 'getDataDetail') {//子页面想要获取待办详情接口数据 会主动发送一个事件过来//如判断type是哪个页面过来的//这里向子页面发送数据回去this.$refs.iframe.contentWindow.postMessage(workDetailsData.workflowList, //待办详情接口返回的数据'*')}//这里可以自定义提示信息的操作//iframe子页面会发送一个方法过来 如第五点if (e.source) {if (e.data.status == 'Approved') {//补充知识//getElementsByClassName() 方法返回文档中所有指定类名的元素集合,作为 NodeList 对象。//NodeList 对象代表一个有顺序的节点列表。NodeList 对象 我们可通过节点列表中的节点索引号来访问列表中的节点(索引号由0开始)。//提示: 你可以使用 NodeList 对象的 length 属性来确定指定类名的元素个数,并循环各个元素来获取你需要的那个元素。let doms = document.getElementsByClassName('el-message')[0]if (doms == undefined) {this.$message.success('审批通过')}this.visible = falsethis.$store.dispatch('tabsBar/delVisitedRoute',this.$route.fullPath)if (this.$route.query.type === 'workflow')this.$router.push(`/tcl/tof/order/sales/workflow`)else this.$router.push(`/tcl/tof/message/workflow/wait-list`)} else if (e.data.status == 'Rejected') {let doms = document.getElementsByClassName('el-message')[0]if (doms == undefined) {this.$message.success('审批拒绝')}this.visible = falseif (this.$route.query.type === 'workflow')this.$router.push(`/tcl/tof/order/sales/workflow`)else this.$router.push(`/tcl/tof/message/workflow/wait-list`)} } else if (e.data.status == 'innerError') {let msgObj = e.datathis.$message({type: msgObj.msgType,message: msgObj.msg,})}}}),

5.子页面方法

that.postMsgToFrame('缺少附件', 'warning')
postMsgToFrame(msg, errType) {if (this.isPorcess) {window.parent.postMessage({type: 'custAddMsg',status: 'innerError',msgType: errType,msg: msg,},'*')} else {this.$message({type: errType,message: msg,})}},

子页面一开始要获取审批流待办详情接口数据来进行一些判断如下

mounted() {// console.log('workDetailsData', workDetailsData)//首先向父页面主动发送事件if (this.$route.query.type == 'delay') {window.parent.postMessage({type: 'getDataDetail',},'*')//父页面发送事件过来,这里接收事件和数据,进行对应的操作,如判断该字段在哪个节点是否需要显示window.addEventListener('message', (e) => {if (e.data) {let showNode = []if (this.options.nodeStatus && this.options.nodeStatus.length > 0) {this.options.nodeStatus.forEach((item) => {showNode.push(item.value)})console.log('这里的数据看看', showNode)if (showNode.indexOf(e.data.name) != -1) {obsData.isFlagShowCol = true}}}})}},

配置平台配置流程

iframe页面判断审批同意接口是否调用自己中心的后端接口

computed: {isPorcess: {get() {let ll = this.$route.queryif (ll.custPostMsgFlg && ll.custPostMsgFlg.indexOf('true') > -1) {return true} else {return false}},},
}

进入页面在mounted判断,需要节点都挂载完毕,然后在方法methods中调用审批方法,是由父页面点击审批通过发送事件过来进行调用

mounted() {if (this.isPorcess) {window.addEventListener('message', this.handleMesg)}
}
methods: {// 点击审批async handleMesg(e) {console.log('e', e)if (e.data.status === 'Approved') { //判断是否同意// this.$refs.Address.$refs.tabs.validate()this.examineApprove()}},async examineApprove() {//先进行表单必填校验操作 通过才调用接口let flag = await this.$refs.Address.validateForm()this.$refs['commentForm'].validate((isPass) => {this.schema_model.comment = this.commentForm.comment //批注自定义this.$refs['filterForm'].validate((valid) => {//校验if (valid && flag && isPass) {const loading = this.$baseLoading({target: 'document.body.tree',})subsidyPriceProcess(this.schema_model).then((res) => {if (res.success == false) {loading.close()this.$message.error('审批不通过,接口报错')} else {loading.close()//iframe 向父组件传值window.parent.postMessage({type: 'commodityApprove',status: 'Approved',},'*')}})} else {this.$message({type: 'error',message: '表单校验不通过!',})return false}})})},
}

相关文章:

关于iframe一些通讯的记录(可适用工作流审批)

一.知识点(1).我们可以通过postMessage(发送方)和onmessage(接收方)这两个HTML5的方法, 来解决跨页面通信问题&#xff0c;或者通过iframe嵌套的不同页面之间的通信a.父页面代码如下<div v-if"src" class"iframe"><iframeref"iframe"id…...

JavaWeb

1、静态Web html、css 2、动态Web 提供给所有人看的数据始终会发生变化。技术栈&#xff1a;Servlet/JSP&#xff0c;ASP&#xff0c;PHP。 Web应用程序&#xff1a;可以提供浏览器访问的程序。 1、这个统一的web资源会被放在同一个文件夹下&#xff0c;web应用程序-->Tom…...

ip段192.168.1.0/24和192.168.0.0/16

192.168.1.0/24192.168.1.1 ~ 192.168.1.254前24位为网络前缀&#xff0c;后8位代表主机号。如下1100 0000&#xff0c;1010 1000&#xff0c;0000 0001&#xff0c;0000 0000192.168.0.0/16192.168.0.1 ~ 192.168.255.254前16位为网络前缀&#xff0c;后16位代表主机号。如下1…...

《爆肝整理》保姆级系列教程python接口自动化(二十二)--unittest执行顺序隐藏的坑(详解)

简介 大多数的初学者在使用 unittest 框架时候&#xff0c;不清楚用例的执行顺序到底是怎样的。对测试类里面的类和方法分不清楚&#xff0c;不知道什么时候执行&#xff0c;什么时候不执行。虽然或许通过代码实现了&#xff0c;也是稀里糊涂的一知半解&#xff0c;这样还好&am…...

【第二章 IOC操作bean管理(XML注入其他类型属性(字面量,外部bean,内部bean,级联赋值)、XML注入集合属性)】

第二章 IOC操作bean管理&#xff08;XML注入其他类型属性&#xff08;字面量&#xff0c;外部bean&#xff0c;内部bean&#xff0c;级联赋值&#xff09;、XML注入集合属性&#xff09; 1.IOC操作bean管理&#xff08;XML注入其他类型属性&#xff09; &#xff08;1&#xf…...

Kotlin-枚举和印章

kotlin-枚举 枚举也是一个对象&#xff0c;枚举对象的定义需要使用enum关键字 枚举对象可以定义函数 假设定义一个星期枚举对象。就是一下写法 enum class Week {星期一,星期二,星期三,星期四,星期五,星期六,星期日;//打印星期几fun printWeek(){println("这是星期枚举对…...

_linux (TCP协议通讯流程)

文章目录TCP协议通讯流程TCP 和 UDP 对比TCP协议通讯流程 下图是基于TCP协议的客户端/服务器程序的一般流程: 服务器初始化: 调用socket, 创建文件描述符;调用bind, 将当前的文件描述符和ip/port绑定在一起;如果这个端口已经被其他进程占用了, 就会bind失 败;调用listen, 声…...

PMP考试详解,新考纲有什么变化?

一&#xff0c;为什么优先考虑PMP持证人员&#xff1f; PMP证书在我国大型企业、跨国企业、央企/国企等单位的招聘中都比较重视&#xff0c;特别是在许多项目投标环节中&#xff0c;明确标明需要有PMP持证人员&#xff0c;才能在投标、竞标中代表公司有资格承担项目。 除此之…...

C++学习笔记-日期和时间

C中可以使用的日期时间API主要分为两类&#xff1a; C-style 日期时间库&#xff0c;位于头文件中。这是原先<time.h>头文件的C版本。 chrono库&#xff1a;C 11中新增API&#xff0c;增加了时间点&#xff0c;时长和时钟等相关接口。 在C11之前&#xff0c;C编程只能使…...

Nordic nRF芯片FDS模块学习

FDS系统学习 文章目录FDS系统学习一、ROM&#xff0c;RAM&#xff0c;FLASH作用二、ROM,RAM和FLASH在单片中的运作原理三、Flash访问模块FDS用法1. FDS在sdk_config.h中的配置2. fds_register()注册3. fds_record_write()写记录4. fds_record_find()查找5. fds_record_open()读…...

JVM 学习(1)—JVM 与 JMM 内存模型简单理解

一、JVM 内存模型概述 (1) 为什么会出现 JVM 内存模型呢&#xff1f; JVM 内存模型是为规范描述 Java 虚拟机在执行 Java 程序时&#xff0c;将程序中的数据和代码存储到计算机内存中的方式和规则。JVM 内存模型定义 Java 虚拟机所使用的内存结构以及内存区域之间的关系&…...

NMS详解

(类别&#xff0c;坐标1&#xff0c;坐标2&#xff0c;坐标3&#xff0c;坐标4&#xff0c;类别分数) step1&#xff1a;对最后一列分数进行排序 &#xff0c;可以看到类别就被打乱了 step2&#xff1a; 弹出得到selected_bboxes作为基准&#xff0c;减少bbox_list。其实就是准…...

考出PMP证书到底有没有用?

我们将从三方面分享&#xff1a; 1. PMP 证书在国内的含金量怎么样&#xff1f; 2. HR 如何看待 PMP 证书&#xff1f; 3. 拿到 PMP 证书后&#xff0c;有哪些变化&#xff1f; 一&#xff0c;PMP证书的含金量 说到 PMP 证书的含金量&#xff0c;相信这个问题是所有学员都…...

寻路库recastnavigation改造

本文是介绍对寻路库recastnavigation 改造&#xff0c;使得使用更加友好。 Git仓库: https://github.com/jiangguilong2000/recastnavigation 首先&#xff0c;我们要做一些前置操作 SDL: 开放源代码的跨平台多媒体开发库 Premake&#xff1a;量跨平台构建系统 环境: VS 2019…...

pandas 一些设置随记

显示所有的行、列 # 显示所有列 pd.set_option(display.max_columns, None) # 显示所有行 pd.set_option(display.max_rows, None)不换行显示 pd.set_option(display.width, 1000) 输出对其 pd.set_option(display.unicode.ambiguous_as_wide, True) pd.set_option(display.…...

SSIM学习

SSIM原文链接&#xff1a;https://www.researchgate.net/profile/Eero-Simoncelli/publication/3327793_Image_Quality_Assessment_From_Error_Visibility_to_Structural_Similarity/links/542173b20cf203f155c6bf1a/Image-Quality-Assessment-From-Error-Visibility-to-Struct…...

selenium自动化测试用例需要关注的几点

自动化测试设计简介注&#xff1a;参看文章地址 我们在本章提供的信息&#xff0c;对自动化测试领域的新人和经验丰富的老手都是有用的。本篇中描述最常见的自动化测试类型&#xff0c; 还描述了可以增强您的自动化测试套件可维护性和扩展性的“设计模式”。还没有使用这些技术…...

harfbuzz 的用法

hb-blob&#xff1a; HarfBuzz Manual harfbuzz 的用法 HarfBuzz 整形 API 的核心是函数。此函数采用一种字体&#xff0c;即 包含一串 Unicode 代码点的缓冲区和 &#xff08;可选&#xff09;字体功能列表作为其输入。它取代了 缓冲区中的代码点&#xff0c;其中包含来自 字…...

JSP 在线学习管理系统myeclipse定制开发sqlserver数据库网页模式java编程jdbc

一、源码特点 JSP 在线学习管理系统是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为SQLServer2008&#x…...

Python学习笔记——PIL库(Pillow库)总结

一、图像数据的格式 ①jpg 支持高级别的压缩&#xff0c;利用部分损耗&#xff0c;使图片变小&#xff0c;方便网络传播。 ②png 无损压缩格式&#xff0c;比jpg略大&#xff0c;较好的保存图片画质&#xff0c;支持透明效果。 ③gif 动图效果&#xff0c;多帧图像组合到…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...