How do you communicate with an iframe?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
Through postMessage. Direct access such as iframe.contentWindow.document only works when both pages share an origin; across origins the same-origin policy blocks it, and postMessage is the sanctioned channel.
// parent -> iframe
iframe.contentWindow.postMessage({ type: "init", token }, "https://widget.example.com");
// inside the iframe
window.addEventListener("message", (event) => {
if (event.origin !== "https://parent.example.com") return; // essential
if (event.data?.type === "init") start(event.data.token);
});
// iframe -> parent
window.parent.postMessage({ type: "resize", height: 480 }, "https://parent.example.com");
The two security rules
Always pass a specific target origin, never "*". With "*" the message is delivered even if the frame has navigated somewhere else, which leaks whatever you sent.
Always check event.origin on receipt. Any page can post to your window. Without that check you are accepting instructions from strangers — this is the single most common mistake with the API, and it turns a communication channel into a vulnerability.
Validate event.data too. It is arbitrary input, so treat it the way you would a request body.
What can be sent
Data is cloned with the structured clone algorithm, so objects, arrays, Date, Map and Set all work. Functions, DOM nodes and class prototypes do not — a class instance arrives as a plain object.
Related mechanics
For a request/response style exchange, MessageChannel gives you a dedicated port pair rather than filtering every message by type. If you control both sides and only need to restrict what the frame can do, add the sandbox attribute and grant capabilities explicitly. And note a common use case — an iframe telling its parent how tall it is — is now better served by ResizeObserver inside the frame reporting through postMessage.
