vue页面内嵌iframe使用postMessage进行数据交互(postMessage跨域通信)

news/2024/10/17 20:24:38/

什么是postMessage

postMessagehtml5引入的API,它允许来自不同源的脚本采用异步方式进行有效的通信,可以实现跨文本文档,多窗口,跨域消息传递.多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案.

vue父页面(嵌入iframe的页面)

在vue中要使用iframe上的postMessage,首先应该获取到iframe实例,有以下几种方式

<iframe :src=“flowSrc” name=“myiframe” ref=“myiframe” id=“myiframe” style=“min-height:800px; width:100%;margin:0;border:0;”> </iframe>

   let iframeWin1 = window.frames["myiframe"];let iframeWin2 = this.$refs.myiframe.contentWindow;let iframeWin3 = document.getElementById("myiframe").contentWindow;

重点: 将iframe的window窗体存储至data对象中会出现跨域报错
重点: 将iframe的window窗体存储至data对象中会出现跨域报错
重点: 将iframe的window窗体存储至data对象中会出现跨域报错
重要的事情说三遍!!!!
也不要用这个方式刷新iframe
let iframeWin2 = this.$refs.myiframe.contentWindow;
iframeWin2.location.reload()
这样操作也会导致跨域
在这里插入图片描述
在这里踩坑了,明明postMessage是支持跨域通信的,但是我在用的时候还是报跨域了,原因就是上述所说的。

父页面传递数据给子页面(vue->iframe)

<template><div class="home"><div class="search-container"><el-input placeholder="请输入内容" v-model="inputValue" clearable class="mind-input"></el-input><div class="search-btn"><el-button type="primary" @click="search">搜索</el-button></div></div><div class="ifarm-container"><iframe :src="flowSrc" name="myiframe" ref="myiframe" id="myiframe" style="min-height:800px; width:100%;margin:0;border:0;"> </iframe></div></div>
</template><script>export default {name: 'HomeView',data() {return {inputValue: '',flowSrc: null,}},created() {this.flowSrc = 'http://localhost/login';  //直接给flowSrc赋值链接},mounted() {// this.passOnIframeData()},methods: {search() {this.sendMessage(this.inputValue)},// 给iframe传递数据sendMessage(msg){let iframeWin = window.frames["myiframe"];//将iframe的window窗体存储至data对象中会出现跨域报错iframeWin.postMessage(msg,"*");},}
}
</script>
<style lang="less" scoped>
.home {width: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;.search-container {display: flex;align-items: center;justify-content: space-between;.mind-input {width: 500px;}.search-btn {flex: 1;margin-left: 20px;}}.ifarm-container {width: 98%;min-height: 800px;margin-top: 20px;border: 1px solid rgb(175, 171, 171);}
}
</style>

子页面接收父页面数据(iframe接收vue传递过来的数据)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>iframe跨域子页面</title>
</head>
<body><div id="mydiv">vue、iframe、postMessage跨域子页面</div>
</body>
<script>//监听message事件,采用冒泡传递方式window.addEventListener("message",receiveMessage,false);function receiveMessage(event){let data = event.dataconsole.log('我是父页面传递过来的', data)document.getElementById("mydiv").innerHTML = data;}
</script>
</html>

子页面向父页面传递数据
在子页面中使用parent.postMessage或者window.parent.postMessage向父元页面发送消息

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>iframe跨域子页面</title>
</head>
<body><div id="mydiv"><button onClick="sendMessage">回传数据</button></div>
</body>
<script>function sendMessage(data){let data = event.dataconsole.log('我是父页面传递过来的', data)window.parent.postMessage("回传数据----哈哈哈哈", "*")}
</script>
</html>

父页面接收子页面的数据

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>跨域父页面</title>
</head>
<body><div id="app"><iframe name="myiframe" ref="myiframe" id="myiframe" src="http://www.a.com/index.html"></iframe></div><script>new Vue({el: '#app',data: {msg: '跨域父页面',iframeWin: null, },methods: {//处理接收的消息receiveMessage(event){let data = event.data;console.log('子组件传递过来的数据', data)}},created(){window.addEventListener("message",this.receiveMessage,false);},//vue实例销毁时销毁一些监听事件destroyed(){window.removeEventListener("message",this.receiveMessage);}})</script>
</body>
</html>

http://www.ppmy.cn/news/51145.html

相关文章

微信小程序原生开发功能合集十三:列表界面的实现

本章实现列表展示组件,包括列表数据加载、筛选、分页加载、快速搜索等功能。   另外还提供小程序开发基础知识讲解课程,包括小程序开发基础知识、组件封装、常用接口组件使用及常用功能实现等内容,具体如下:    1. CSDN课程: https://edu.csdn.net/course/detail/379…

3 redis线程IO模型

1 IO模型 1.1 IO IO (Input/Output&#xff0c;输入/输出)即数据的读取&#xff08;接收&#xff09;或写入&#xff08;发送&#xff09;操作&#xff0c;通常用户进程中的一个完整IO分为两阶段&#xff1a;用户进程空间<–>内核空间、内核空间<–>设备空间&…

Python Web开发技巧III

字符串类型与日期类型的互换 字符串 > 日期类型与 日期类型 > 字符串&#xff0c;就单纯SDK操作&#xff0c;简洁写法&#xff0c;开发使用这种写法就OK了。 from datetime import datetime, date# str -> datetime res1 date(*map(int, "2023-04-25".sp…

LeetCode 2418. 按身高排序

【LetMeFly】2418.按身高排序 力扣题目链接&#xff1a;https://leetcode.cn/problems/sort-the-people/ 给你一个字符串数组 names &#xff0c;和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n 。 对于每个下标 i&#xff0c;names[i] 和 heights[i…

根据身高排序(力扣2418)

问题&#xff1a; 给你一个字符串数组 names &#xff0c;和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n 。 对于每个下标 i&#xff0c;names[i] 和 heights[i] 表示第 i 个人的名字和身高。 请按身高 降序 顺序返回对应的名字数组 names 。 示例 …

第4章:运算符

1.算术运算符 ① SELECT 10010,100-35.5,100*2,100/2,100%30 FROM DUAL;②在sql中“”没有连接作用&#xff0c;表示加法运算&#xff0c;字符串转换为数值&#xff08;隐式转换&#xff09;。非数值看作0处理 SELECT 1001 1 FROM DUAL;SELECT 100 a FROM DUAL;③加法运算…

数字化转型危与机,20年老厂的升级之路

“投资大、周期长、见效慢”&#xff0c;是每一家企业在考虑数字化战略时&#xff0c;都会纠结的问题。 打江山容易&#xff0c;守江山难 企业在快速扩张的过程中&#xff0c;往往可以不需要过多的考虑细节的问题&#xff0c;跑马圈地的打法会更加有效。 但是市场占有量开始饱…

Turndown 源码解析:一、辅助函数

extend() Object.assign的补丁。 function extend (destination) {for (var i 1; i < arguments.length; i) {var source arguments[i];for (var key in source) {if (source.hasOwnProperty(key)) destination[key] source[key];}}return destination }repeat() Stri…