自学内容网 自学内容网

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 导致子应用服务器繁忙,接口无法发送消息。如果有更好的方案,欢迎评论区提出。


原文地址:https://blog.csdn.net/Dreamy_LIN/article/details/143059064

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!