iframe之间的通信方式的实际应用---在Vue框架下获取数据、处理文件上传和跨窗口通信

 

iframe标签实现html主页面嵌套html子页面,父子页面间的传值有以下两种方式


如果是跨域的页面,需要拿到消息接收页面的 contentWindow 才可以发送

window.parent--------获取父页面window对象,如果没有父页面将返回自身

window.top--- 获取顶层页面window对象---只能用于同源下,否则获取不到外层页面的信息



 

 父页面

 created() {
    // 父页面发送消息给iframe页面
    let iframe = this.$refs.iframeDom
    let _window = iframeDom.contentWindow // iframe的window对象 可以事件监听,事件传     递
    let _document = iframeDom.contentDocument // 可以获取节点
    // postMessage 有两个参数,第1个是传递的消息,第2个是传递到哪去 *表示所有,可      直接传嵌套的网址
    _window.postMessage({ type: '自定义传递类型,后续可根据不同类型做不同处理',              data: '消息内容体' }, '*')

    // 获取iframe的dom的值
    let _document = iframeDom.contentDocument
    let textAreaDom = _document.querySelector('获取的dom类名或id')
    let _value = textAreaDom.value
    let _position = textAreaDom.getAttribute('data-pos')



  },
  mounted() {
    // 父页面监听iframe消息
    window.addEventListener('message', (e) => {
      console.log('iframe数据', e.data)
    })

    // 获取要修改的iframe值的dom元素绑定事件
    let iframe = this.$refs.iframeDom
    iframe.addEventListener('load', () => {
      let _document = iframeDom.contentDocument
      let textAreaDom = _document.querySelector('获取的dom类名或id')
      textAreaDom.addEventListener('change', (e) => {
        e.tartget.selectionStart // 获取光标位置
        textAreaDom.setAttribute('data-pos', e.tartget.selectionStart)
      })
    })
  }

子页面 

mounted() {
    // iframe页面监听父页面发过来的消息
    window.addEventListener('message', (e) => {
      console.log('父页面数据', e.data)
    })
  },
  methods: {
    // iframe页面给父页面发送消息
    transinformation() {
      // 获取父级window
      // window.parent(最近的上一级父页面)window.top (最顶层的父页面,即有多层嵌套iframe的时候使用)
      window.parent.postMessage({ type: '自定义传递类型,后续可以根据不同类型做不同处理', data: '消息内容体' }, '*')
    }
  }
          <div class="ira">
        <lots-button>提交</lots-button>
        <el-tabs v-model="activeName" class="el-tabs">
        </el-tabs>
        <iframe :src="mipurl" title="mip" width="100%" frameborder="0" ref="iframeRef"> 
        </iframe>
    </div>


const getIFlowDetail = (mipFdId) => {
            iflowDetail({ mipFdId }).then((res) => {
                if (res && +res.code === 0) {
                    const {mipAttacheName, mipAttachment, mipMsg}
                     = res.data.invAdAcountHeaderDto;
                    uploadAttchmentBase64.value = mipAttachment;
                    totalData.val = res.data.invAdAcountDetailDtos;
                     mipurl.value = mipPath;
                    form.mipMsg = mipMsg;
                    form.fileList.push(uploadAttchmentBase64.value);
                }
            });
        };
        const mipSubmit = () => {
            elForm.value.validate((valid) => {
                if (valid) {
                    window.frames[0].postMessage('getApprovalData', mipurl.value);
                } else {
                    console.log('测试', valid);
                }
            });
        };
        const submitJson = ref();
        const messageFunc = (event) => {
            submitLoading.value = true;
            submitJson.value = event.data.data;
            submitJson.value.formParam.formInstanceId = 'inventoryMov';
            // eslint-disable-next-line no-const-assign
            submitJson.value = JSON.stringify(submitJson.value);
            iflowSubmit({
                adHeaderId: adHeaderId.value,
                file: formdataFile.value,
                mipMsg: form.mipMsg,
                approveJson: submitJson.value,
            }).then((res) => {
                submitLoading.value = false;
                if (res && +res.code === 0) {
                    window.location.reload();
                    ElMessage.success('提交成功!');
                }
            });
        };

        // 文件转换为二进制格式文件流
        const formdataFile = ref('');
        const fileName = ref('');
        const uploadOnChange = (file) => {
            const num = 20;
            const checkSize = file.size / FILE_SIZE / FILE_SIZE < num;
            if (!checkSize) {
                ElMessage.error({
                    message: '上传文件大小不能超过20MB',
                    center: 'true',
                });
                return;
            }
            utils.getBase64(file.raw).then((res) => {
                uploadAttchmentBase64.value = res;
            });
            // 将文件转为二进制格式存储
            const binaryFile = new File([file.raw], file.raw.name, {
                type: file.raw.type,
            });
            formdataFile.value = binaryFile;
            fileName.value = binaryFile.name;
            form.fileList.push(file);
        };
        onMounted(() => {
            getIFlowDetail(mipFdId);
            window.addEventListener('message', messageFunc, false);
        });



如果表单有效, window.frames[0].postMessage 向内嵌的iframe发送消息。
submitJson 是一个响应式引用,用于存储提交的数据。
messageFunc 是一个事件处理函数,它在接收到window的message事件时被触发,
主要负责处理提交操作。


window.frames[0].postMessage('mbpm_getApprovalData', mipurl.value);

如果表单有效postMessage 方法向页面中的第1个内嵌的iframe(window.frames[0])发送一个消息。
消息的内容是字符串 'mbpm_getApprovalData',而目标URL则是 mipurl.value 所存储的值。
跨窗口通信的方式进行安全通信。

window.addEventListener('message', messageFunc, false);

window对象添加了一个事件监听器,用于监听 'message' 事件。
当window对象接收到其他窗口或iframe发送的消息时,messageFunc 函数将被调用。
第三个参数 false 表示在捕获阶段不处理事件,只在冒泡阶段处理。
通过这种方式,嵌入在当前页面中的其他窗口或iframe可以与主窗口进行通信,
实现数据交换或触发特定操作。

<button onclick="sendMessage()">发送消息</button>

<script>
const iframe = document.querySelector("iframe");
  var data = {
    name: "rootPage",
    data: "我是主页面的数据"
  };

const sendMessage=()=> {
  iframe.contentWindow.postMessage(data, "http://127.0.0.1:5501"); // 父页面监听 message 事件
}
</script>

// 获取除了自身页面,外层所有页面的源(从内向外)
location.ancestorOrigins

我在最内层子组件打印这个
{
    "0": "http://127.0.0.1:5501", // 父页面
    "1": "http://127.0.0.1:5500" // 主页面
}

原文链接:https://blog.csdn.net/weixin_60547084/article/details/126536252

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Vue ,当你需要在不同的 iframe 之间进行通信时,可以使用 HTML5 提供的 postMessage() 方法。该方法可以在两个不同的窗口之间传递消息。 下面是一个示例,展示了如何在 Vue 组件使用 postMessage() 方法进行 iframe 之间通信: 在父页面,可以使用以下代码来发送消息: ``` const targetOrigin = 'http://example.com'; // iframe 的源 const iframe = document.getElementById('frameId'); // 获取 iframe 元素 iframe.contentWindow.postMessage('Hello from parent', targetOrigin); ``` 在子页面,可以使用以下代码来监听消息: ``` window.addEventListener('message', event => { // 判断消息来源是否合法 if (event.origin !== 'http://example.com') { return; } // 处理消息 console.log('Received message from parent:', event.data); }); ``` 在 Vue 组件,可以将这些代码封装成方法,以便在需要时调用。例如,在父组件,可以定义一个 sendMessage() 方法: ``` methods: { sendMessage(message) { const targetOrigin = 'http://example.com'; // iframe 的源 const iframe = document.getElementById('frameId'); // 获取 iframe 元素 iframe.contentWindow.postMessage(message, targetOrigin); } } ``` 在子组件,可以定义一个监听消息的方法: ``` mounted() { window.addEventListener('message', event => { // 判断消息来源是否合法 if (event.origin !== 'http://example.com') { return; } // 处理消息 console.log('Received message from parent:', event.data); }); } ``` 当需要发送消息时,可以在父组件调用 sendMessage() 方法;当需要接收消息时,可以在子组件监听 message 事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小可爱的小飞云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值