Published on

使用 postMessage 實現 iframe 父子頁面通訊

Authors
  • Name
    Twitter

Main Page

Main Page 會載入 Child iframe,並且透過 postMessage 傳送訊息給 Child iframe。 等到 Child iframe 載入完成後,會透過 message 事件監聽 Main Page 傳送的訊息。

<h1>Main Page</h1>
<iframe id="child" src="./child.html"></iframe>
<script>
	console.log('[Main Page] Page loaded');
	const iframe = document.getElementById("child");
	iframe.addEventListener('load', () => {
		console.log('[Main Page] Sending message to child');
		iframe.contentWindow.postMessage({ msg: "Hello from parent" }, "*");
	});
</script>

Child iframe

<h1>Child Page</h1>
<script>
	console.log('[Child Page] Page loaded');
	window.addEventListener("message", (event) => {
		console.log('[Child Page] Message received:', event.data);
		console.log('[Child Page] Origin:', event.origin);
	});
</script>

在 Main Page 會 log 出

  1. [Main Page] Page loaded
  2. [Child Page] Page loaded
  3. [Main Page] Sending message to child
  4. [Child Page] Message received: {msg: 'Hello from parent'}
  5. [Child Page] Origin: http://127.0.0.1:5500

log on browser console

main-iframe

log on child page console

由於安裝 react 的 devtools 後,會在 console 顯示 react 的 log:

react-devtools-hook-installer

{
    "source": "react-devtools-hook-installer",
    "payload": {
        "handshake": true
    }
}

react-devtools-hook-settings-injector

{
    "source": "react-devtools-hook-settings-injector",
    "payload": {
        "settings": {
            "appendComponentStack": true,
            "breakOnConsoleErrors": false,
            "showInlineWarningsAndErrors": true,
            "hideConsoleLogsInStrictMode": false
        }
    }
}

react-devtools-content-script

{
    "source": "",
    "hello": true
}
overview log on child page console child-page

main.html & child.html code

main-iframe-code

總結

核心概念

  1. 使用 postMessage 可以在不同視窗或 iframe 之間進行跨域通訊
  2. 使用 iframe.addEventListener('load', callback) 監聽載入完成
  3. 在父頁面中,可以透過 iframe.contentWindow.postMessage() 發送訊息
  4. 在子頁面中,需要監聽 message 事件來接收訊息
  5. 訊息內容可以包含任何可序列化的資料
  6. 可以透過 event.origin 檢查訊息的來源,增加安全性