当前位置: 首页 > 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;多帧图像组合到…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...

AD学习(3)

1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分&#xff1a; &#xff08;1&#xff09;PCB焊盘&#xff1a;表层的铜 &#xff0c;top层的铜 &#xff08;2&#xff09;管脚序号&#xff1a;用来关联原理图中的管脚的序号&#xff0c;原理图的序号需要和PCB封装一一…...