美文网首页
前端多系统集成通信

前端多系统集成通信

作者: Weastsea | 来源:发表于2018-04-20 18:53 被阅读0次

    1:目标

    集成多个相互独立的系统展示在一个页面上,多个系统可以相互进行数据通信。

    2:应用场景

    假设页面内嵌两个系统,就是一个父系统集成2个子系统

    一般会存在3种信息传递场景:
    1: 父——>子 由父系统把消息传递到子系统

    2:子1——>父——>子2🈶子1把消息传递给子2,但是需要父系统作为代理中转

    3:子——> 父 由子系统把消息传递给父系统

    3:依赖的主要技术——HTML5跨文档消息传递

    跨文档消息传送(cross-document messaging),有时候简称为 XDM,指的是在来自不同域的页面间 传递消息。例如,www.wrox.com 域中的页面与位于一个内嵌框架中的 p2p.wrox.com 域中的页面通信。 在 XDM 机制出现之前,要稳妥地实现这种通信需要花很多工夫。XDM 把这种机制规范化,让我们能 既稳妥又简单地实现跨文档通信。——JavaScript高级程序设计

    在此不再详细赘述此技术,可通过相关书籍(推荐《JavaScript高级程序设计》)和博客自行学习。

    4:设计思路以及细节处理

    注意: 前端框架使用vue

    4.1: 我们首先解决从父——>子

    步骤:

    1. 首先在父系统中嵌入iframe,注册2个子系统
      http://localhost:8082http://localhost:8080是启动的两个前端应用,分别代表app1和app2。父系统是 http://localhost:8081
    <iframe id='app1' src="http://localhost:8082" frameborder="0" width="550" height="800">
    </iframe>
    <iframe id='app2' src="http://localhost:8080" frameborder="0" width="550" height="800">
    </iframe>
    

    2: 父系统触发事件,例如click事件,通过id获取子系统的window,然后发送消息,例如触发的事件名为:postMessage

    //封装方法
     postMessage () {
          let app1Window = window.document.getElementById('app1').contentWindow
          let app2Window = window.document.getElementById('app2').contentWindow
          let postMstData = {
            //{'data':''}}需要传递的数据, ip字符串:目标targetd的ip地址(一定要拼写正确)
            'app1Window': [app1Window, {'data': '我是APP1'}, 'http://localhost:8082'],
            'app2Window': [app2Window, {'data': '我是APP2'}, 'http://localhost:8080']
          }
          this.postMstHandler(postMstData)
        },
    // 父系统进行广播
        postMstHandler (obj) {
          for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
              if (obj[key][0].postMessage) {
                obj[key][0].postMessage(obj[key][1], obj[key][2])
              }
            }
          }
        }
    

    3: 子系统接收数据
    以app1为例:
    在vue中,可以写在mounted钩子函数中;
    在原生js中,可以写在window.onload = function () {}中,页面渲染的时候进行接收消息事件注册

     mounted () {
          let _this = this
          //  注册window的message事件来监听和接收消息
          window.addEventListener('message', function (event) {
            // event.origin: 表示来源地址,此处必须写父系统的域名
            if (event.origin === 'http://localhost:8081') {
              _this.postMst = event.data['data']
              // 处理数据逻辑
               ......
            }
          })
        }
    

    页面展示效果:


    4.2: 解决从子——>父

    以app1为例
    app1系统触发事件,例如click事件,直接获取parent对象(父系统window),通过parent发送消息,例如触发的事件名为:postMessage

     postMessage () {
            if (parent.postMessage) {
            // 此处域名写父系统的
              parent.postMessage({'data': '我是从app1发往父系统的字符串'}, 'http://localhost:8081')
            }
          },
    

    然后需要在父系统里注册message事件,来监测从app1传来的消息

    mounted () {
       var This = this
       window.addEventListener('message', function (event) {
         if (event.origin === 'http://localhost:8082') {
           //event.data为 {'app1': data, location: 'http://localhost:8080'}
           let keys = Object.getOwnPropertyNames(event.data)
           console.log(keys)
           if (keys.length === 2) {
             // 子 -> 父 -> 子
             let app = keys[0]
             let appWindow = window.document.getElementById(app).contentWindow
             let postMstData = {
               'appWindow': [appWindow, {'data': event.data[app]}, event.data.location]
             }
             console.log(postMstData)
             This.postMstHandler(postMstData)
           } else {
             // 子 -> 父
             This.postMst = event.data['data']
           }
         }
       })
     },
    

    页面展示效果:


    4.3: 解决从子——>父——>子

    解决办法是需要通过父系统作为代理来进行传递数据,我们从app1 将数据通过父系统传递给app2
    首先在app2触发消息传递

     postMessage () {
            // 此数据项,表明APP1 要向哪一个APP发送消息,以父模块作为代理
            let data = '我是从app1发往app2的字符串'
            if (parent.postMessage) {
              parent.postMessage({'app2': data, location: 'http://localhost:8080'}, 'http://localhost:8081')
          },
    

    父系统接收数据,做转发的准备

     mounted () {
       var This = this
       window.addEventListener('message', function (event) {
         if (event.origin === 'http://localhost:8082') {
           // {'app1': data, location: 'http://localhost:8080'}
           let keys = Object.getOwnPropertyNames(event.data)
           console.log(keys)
           if (keys.length === 2) {
             // 子 -> 父 -> 子
             let app = keys[0]
             let appWindow = window.document.getElementById(app).contentWindow
             let postMstData = {
               'appWindow': [appWindow, {'data': event.data[app]}, event.data.location]
             }
             console.log(postMstData)
             This.postMstHandler(postMstData)
           } else {
             // 子 -> 父
             This.postMst = event.data['data']
           }
         }
       })
     },
    

    app2注册message事件,来接收从app来的消息

     mounted () {
          let _this = this
          window.addEventListener('message', function (evnet) {
            console.log(event.origin)
            if(event.origin === 'http://localhost:8081') {
              _this.postMst= event.data['data']
            }
          })
        },
    

    页面展示效果如下:


    相关文章

      网友评论

          本文标题:前端多系统集成通信

          本文链接:https://www.haomeiwen.com/subject/mxdzkftx.html