iframe+postMessage进行跨域通信

本文介绍了如何利用window.postMessage方法在layui+jq的页面中与嵌入的Vue子页面进行跨域通信。通过在Vue子页面发送消息通知父页面加载完成,然后父页面通过监听message事件来传输数据,实现了两者间的双向通信。这种方法对于解决不同源页面间的通信问题非常有效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

参考 iframe+postMessage实现跨域通信

项目需要在layui+jq的网站中引入一个vue的页面,
layui+Jq网站地址:http://192.168.2.86:9988/
vue网站地址:http://192.168.2.86:8081/#/formShow

要解决跨域的问题,以及通信的问题


提示:可直接看代码理解

一、window.PostMessage

.. 该window.postMessage()方法安全地启用Window对象之间的跨源通信;例如,在页面和它产生的弹出窗口之间,或者在页面和嵌入其中的iframe之间。 通常,当且仅当它们源自的页面共享相同的协议、端口号和主机(也称为“同源策略”)时,允许不同页面上的脚本相互访问。window.postMessage()提供一种受控制的机制来安全地规避这种限制(如果使用得当)。 从广义上讲,一个窗口可以获得对另一个窗口的引用(例如,可以使用targetWindow=window.opener),然后使用targetWindow.postMessage() 在其上发送一个MessageEvent。然后,接收窗口可根据需要自由处理此事件。传递给window.postMessage()的参数(即“message”)通过事件对象暴露给接收窗口。

参考
W3Cshool-window方法:postMessage()

二、使用步骤

1.前提

现有页面 A:http://192.168.2.86:9988/formDesign
需要引入子页面B http://192.168.2.86:8081/#/formShow

页面A代码

 <iframe frameborder="0" height="99.7%" id="review"
              src="http://192.168.2.86:9988/#/formShow"
              scrolling="auto" width="100%"></iframe>

页面B为正常展示代码。

2.通信

由于B网站是VUE,使用windows.postMessage前提是要确保iframe要加载完毕。我尝试过使用onload方法来判断,但是一直报错,未找到原因,我只有采取其他办法

B网站代码

<script>
export default {
  data: function () {
    return {
      jsonData: {},
      jsonValue: {},
      onlyRead: false
    }
  },
  mounted () {
    // 通知父页面,此页面已经渲染完毕
    var data = {
      type: 'notice',
      data: true
    }
    ///因为这个是子页面,被嵌入页面,所以使用parent就能找到父页面
    //parent.postMessage("数据,不用再单独序列化", "目标地址,嵌入此页面的父页面地址")
    parent.postMessage(data, 'http://192.168.2.86:9988/formDesign')

    var glbthis = this
    window.onmessage = function (event) {
    //确保消息来源为http://192.168.2.86:9988才进行处理,
    //不然的话也会有来自http://192.168.2.86:8081 自身的消息,暂时不知道原因
      if (event.origin === 'http://192.168.2.86:9988') {
       if (event.data.type === 'designjson') {
          glbthis.jsonData = JSON.parse(event.data.data)
        }
        if (event.data.type === 'designvalue') {
          glbthis.jsonValue=JSON.parse(event.data.data)
        }
      }
    }
  }
}
</script>

A网站代码

<script>
  layui.use('layer', function () {
    var layer = layui.layer;
    window.onmessage = function (event) {
      if (event.origin === 'http://192.168.2.86:8081 ') {
        //子页面渲染完毕后会发送消息过来。进行类型判断,收到渲染完成消息,再进行数据通信
        if (event.data.type == "notice" && event.data.data) {
          ///这个是获取子页面的window对象
          var iframeWin = document.getElementById('review').contentWindow;
		  //自定要通信的数据,我在这里加上type,会传送很多次不同的数据,手动加上type区分
		  //这个是传输表单设计json
          var postData = {type: "designjson", data: designjson.jsonData}
          iframeWin.postMessage(postData, 'http://192.168.2.86:8081/#/formShow');
          //传输表单填写的的值
          postData = {type: "designvalue", data: expertReviewJsonData}
          iframeWin.postMessage(postData, 'http://192.168.2.86:8081/#/formShow');
        }
      }
    }
  })
</script>

总结

目前还只能算是知道怎么用,未去深究其他。但是这种组合应该能解决很多问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值