Lesson 0003 · ~10 minutes

event.source is a handle

One skill: when a message arrives, reply on event.source with event.origin as targetOrigin.

Win for this lesson

You can say this: “I do not look up the iframe to reply. I use event.source. I pass event.origin. If I have two iframes, I compare event.source === iframe.contentWindow.”

1. The problem

A page has two widgets.

Each widget is an iframe.

Both send data to you.

You must reply to the sender.

You must not reply to the other widget.

You already know how to get a handle.

The event already holds the handle of the sender.

2. Two fields

A window message has both of these:

They are not the same kind of value.

On a later lesson, event.source can also be a MessagePort. This lesson is the window case.

3. How you reply

window.addEventListener("message", (event) => {
  if (event.origin !== "https://widget.example") return;
  event.source.postMessage({ type: "ack" }, event.origin);
});

event.source picks the window. event.origin is the targetOrigin for that send. (MDN)

That origin is the sender at send time. If the window goes to a new origin before the reply arrives, the browser discards the reply. There is no error. That is the same rule as lesson 1.

React, same rule
useEffect(() => {
  function onMessage(event) {
    if (event.origin !== "https://widget.example") return;
    event.source.postMessage({ type: "ack" }, event.origin);
  }
  window.addEventListener("message", onMessage);
  return () => window.removeEventListener("message", onMessage);
}, []);

4. Which iframe

You compare the handle to contentWindow. (MDN)

if (event.source === alphaRef.current.contentWindow) {
  // the alpha iframe sent this
}

Do not use event.origin to pick the element. Two iframes can have the same origin.

On this lesson file, both children stamp event.origin as the text null. A string check cannot tell them apart. The handle check can.

5. Do these steps

The box below has two real iframes: Alpha and Beta.

  1. In Alpha, click Ping parent. The last-sender line must say source===alpha.contentWindow true.
  2. Click Reply to source. Alpha must show the reply. Beta must not.
  3. In Beta, click Ping parent. The last-sender line must say source===beta.contentWindow true.
  4. Click Reply to source. Beta must show the reply.
  5. Click Reply to the other. The iframe that did not ping must show that data.

6. Practice

Do the five steps first. Then answer these questions.

Question A

You receive a message. You need to reply to the sender.

Question B

Two iframes sent. You need the iframe element.

Question C

A message arrives. What are event.origin and event.source?

Question D

You reply with targetOrigin set to event.origin.

Question E

On this file page both event.origin values match.

7. Remember

Ask your teacher If a sentence is not clear, ask. If a lab step does not match the text, ask. That is part of the method.

Primary source (read next)

MDN — The dispatched event. Then mapping message sources to iframes.