将 postMessage 从父级用于 iframe 时出现原始错误(无法在“DOMWindow”上执行“postMessage”)

Origin error when using postMessage from parent to iframe (Failed to execute 'postMessage' on 'DOMWindow')

提问人:Horkos 提问时间:6/2/2023 更新时间:6/2/2023 访问量:760

问:

我正在尝试通过发送包含字符串化对象的消息来使两个 React 应用程序进行通信。

父级 (http://localhost:3000) 通过如下方式发送消息:postMessage

    let iframe = document.querySelector("iframe")

    useEffect(() => {
        if (!!localStorageObject && !!iframe) {
            iframe?.contentWindow?.postMessage(localStorageObject, "http://localhost:3001")
        }
    }, [localStorageObject, iframe])

    // ...file and start of return

   <iframe
       style={{minHeight: window.outerHeight, width: '100%', border: "none"}}
       referrerPolicy="strict-origin-when-cross-origin"
       src={myUrlWithParams}
       title="App"
       allow="clipboard-write"
       id={"iframe"}
   />

iFrame (http://localhost:3001) 没有收到消息,至少不会立即收到(我必须等待 react 软刷新才能显示日志)。

首先抛出的错误是:

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://localhost:3001') does not match the recipient window's origin ('http://localhost:3000').
JavaScript ReactJS DOM iframe 消息

评论

0赞 Paulo Fernando 6/2/2023
这看起来很骇人听闻,为什么需要 2 个应用程序才能通过 iframe 进行通信,难道它不能只是一个应用程序吗?

答:

0赞 Kaiido 6/2/2023 #1

这是因为调用此方法时,您的 iframe 文档尚未加载,因此您收到的是原始文档之一,而不是预期的文档。postMessage()contentWindowabout:blank

有人可能会争辩说,这里的错误消息有点令人困惑,并且您的开发工具可能会更好(也?)报告该位置的来源(即使已经检查的是全局文档)。about:blankoriginpostMessage()

但无论如何,要解决该问题,请等待您的 .(对不起,我不是 reactJS 忍者,所以我会让你找到最好的方法)。load<iframe>

下面是一个应用了解决方案的原版重现设置:https://jsfiddle.net/382pz5er/(外包,因为 StackSnippet 的 null 原始帧在这里是一个不好的例子)。