iframe token 通信。iframe 子应用无法收到 message

问题描述

父应用内嵌 iframe 子应用,需要在一开始传递 token。这种情况下监听 message 的时机(代码放置的位置很重要),否则可能出现获取不到 message 的问题。

如果采用等子应用加载完,再 postMessage 给父应用,父应用再传递 token。这可能导致过多的双向 postMessage ,使得子应用服务器繁忙,接口无法发送消息。

解决思路

方案一

url + token,没用这种,觉得不安全。就算要用也要将 token 二次加密传送,才更安全些。

方案二

由于我的是不同域名的通信,因此直接采用 postMessage 通信方式。

父应用在内嵌 iframe 的页面,监听 iframe 初始化加载

onBeforeMount(async () => {
  iframeRef.value &&
    (iframeRef.value.onload = () => {
      iframeRef.value?.contentWindow?.postMessage(
        { type: 'token', data: 'token-xxxx' },
        '*'
      )
    })
})

// iframeSrc
const iframeSrc = computed(() => {
  return `${import.meta.env.VITE_PUBLIC_CHAT}?useCustomApi=true`
})

// template
<iframe
  ref="iframeRef"
  :src="iframeSrc"
  frameborder="0"
   class="h-[calc(100%-42px)] w-full"
></iframe>

子应用最早监听的位置——入口: main.ts
得到 token 后,再 reload()。其他情况下不需要 reload()
这里的 token 可以存储在 localStorage 或者 sessionStorage。监听页面卸载时,删除 token。

window.addEventListener('message', messageEventHandler)
window.onbeforeunload = () => {
  window.removeEventListener('message', messageEventHandler)
}

export const messageEventHandler = (e: MessageEvent) => {
  const { type, data } = e.data
  const authStore = useAuthStore()
  const parentStore = useParentStore()
  switch (type) {
    case 'token':
      if (!authStore.token) {
        authStore.setToken(data)
        window.location.reload()
      }
      break
    }
}

结论

方案二,可以解决获取不到 message 的问题。或者过多的双向 postMessage 导致子应用服务器繁忙,接口无法发送消息。如果有更好的方案,欢迎评论区提出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值