postMessage实现iframe传值

需求:需要在系统中嵌入一个子项目,同时父项目与子项目是分开部署,子项目需要拿到父项目的token以及一系列参数。

第一步:父项目: angular版

 <iframe
    width="100%"
    style="min-height: calc(100vh - 70px);background: #ffffff"
    frameborder="0" marginheight="0px"
    sandbox="allow-top-navigation allow-scripts allow-same-origin"
    id="workFlowIframe"
    src="http://192.168.9.236:1024/">
</iframe>

在angular的初始化声明周期中加入对子项目的postMessage监听事件,当子项目发送message来时可以捕捉到

 ngOnInit(): void {
    this.postToIframe();
  }

  ngOnDestroy() {
    console.log('destroy');
    //在离开页面时必须手动清空数据,因js不会主动回收document全局对象
    //如果用angular的viewChild去捕捉dom,js会主动回收
    this.cleanup()
  }

messageListener =null

 postToIframe() {
    const iframe: any = document.getElementById('workFlowIframe');
    if (!iframe) {
        return;
    }
    const token = this.getToken();
    const businessType = this.getBusinessType();
    const lang = this.getSystemLanguage();
    const header = {}
    if (businessType !== null) {
      header['businessType'] = businessType;
    }
    header['authorization'] = token;
    header['lang'] = lang;

    this.messageListener = function(event) {
      //175为线上环境,236为本地环境
      if (event.origin !== 'http://192.168.199.175:1024' && event.origin !== 'http://192.168.9.236:1024') return;
      if(event.data === 'recieved') {
        console.log(1,event);
        iframe.contentWindow.postMessage(header, '*');
      }
    }
    window.addEventListener('message', this.messageListener, false);
  }

cleanup() {
  // 移除事件监听器
  if (this.messageListener) {
    window.removeEventListener('message', this.messageListener);
  }
  this.messageListener = null;
  // 移除 iframe
  const iframe: any = document.getElementById('workFlowIframe');
  if (iframe) {
    iframe.remove();
  }
}

第二步: 在子项目(vue)的beforeMounted生命周期中发送给父项目message,告诉父项目自己已经可以接受数据

    beforeMount() {
      console.log('发送到父')
      window.parent.postMessage('recieved', '*');
    },

第三步: 当子项目发送的message被父项目接收到之后,父项目把参数用postMessage发送给子项目,子项目在main.js中监听

window.addEventListener('message', function(event) {
  if (event.origin !== 'http://localhost:4200' && event.origin !== 'http://192.168.199.175:12121') return;
    localStorage.setItem('header', JSON.stringify(event.data));
    console.log(2,event);
    store.commit('changeLang',event.data.lang)
    locale.use(event.data.lang === 'en_US' ? enLocale : zhLocale)
  }, false);

ps: 整体思路类似“握手”,保证了子项目能如期获取到数据,而不会发生在父项目发送之前导致消息错过,或者子项目的初始化请求前,导致请求来不及拿到请求头而导致请求失败。同时可以在父项目在任意初始化后的节点:例如token主动刷新,语言系统切换等情况再次主动发送postMessage到子项目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值