The postMessage
call allows an asynchronous communication channel between different browsing contexts, such as with IFrames and web workers, where direct function calls don't work. It works by sending a message to the other side, then the receiving end can listen to message
events.
For example, the page can communicate with an IFrame via postMessage
and send events to each others' windows. The iframe.contentWindow.postMessage()
call sends a message to the IFrame, while the window.parent.postMessage()
sends a message back to the main page. The two ends can listen to messages from the other using window.addEventListener("message", (event) => {...})
.
// index.html
const iframe = document.querySelector("iframe");
window.addEventListener("message", ({data}) => {
// 3: receive response
console.log("Message from iframe: " + data);
});
// 1: send request
iframe.contentWindow.postMessage([5, 2]);
// iframe.html
window.addEventListener("message", ({data}) => {
// 2: send response
window.parent.postMessage(event.data[0] + event.data[1]);
});
For web workers, each worker has a separate message handler. The page can send a message to a specific worker using the worker.postMessage()
call and listen for events from that worker using worker.addEventListener("message", (event) => {...})
. On the other side, the worker sends and receives events using the global functions postMessage()
and addEventListener()
:
// index.html
const worker = new Worker("worker.js");
worker.addEventListener("message", ({data}) => {
console.log("Message from worker: " + data); // 3
});
worker.postMessage([5, 5]); // 1
// worker.js
addEventListener("message", (event) => {
postMessage(event.data[0] + event.data[1]); // 2
}, false)