Windows that talk

postMessage
the lab — press each button, watch the status line
waiting…

Frame 1 — ours (frame.html, same origin; view its source below / separately)

Frame 2 — https://example.com (a genuinely different origin; stands in for any site that isn't ours)

the three buttons, plainly:

① document.getElementById('frame').contentWindow.hello('hello iFrame');        // same origin → runs
② document.getElementById('frame2').contentWindow.hello('hello iFrame');      // cross origin → SecurityError
③ frame.contentWindow.postMessage({message:'hello iFrame'}, '*');             // the bridge → delivers

Frame sources are ordinary URLs — right-click inside each frame → View source to read the receiving code the way the lesson does. example.com is purely a stand-in for "any origin that isn't ours".

Method — what each button teaches
  1. ① (same origin): the parent grabs the frame by id, grabs its contentWindow, and calls hello('hello iFrame') straight into it. Alert fires inside the frame's document. Nothing prevents cross-window same-origin reach — same protocol (https), same domain, same port.
  2. ② (cross origin): the identical call against https://example.com throws — the browser severs the line and the error lands on our status line (and in DevTools → Console), something like Permission denied to access property "hello" on cross-origin object. The origin trifecta (protocol, domain, port) decides "same" vs "different"; break one and it's different.
  3. ③ (the bridge): postMessage({message:'hello iFrame'}, '*') is designed for news being passed papers over the fence: the frame registered addEventListener('message', …), our message arrives on that listener, and the frame alerts it. Works across origins — which is exactly why both ENDS must now check trust: who is allowed to send (receiver's event.origin), and who is allowed to receive (sender's targetOrigin). Labs 29–31 break each side.
  4. Frame sources are ordinary URLs: right-click inside each frame → View source to read the receiving code like the lesson does. example.com is purely a stand-in for "any origin that isn't ours".
Spoiler — the full flow in one file, then the vocabulary

Lesson vocabulary anchored to what you just saw: window.postMessage(msg, targetOrigin) — sender side, where targetOrigin is YOUR claim of where the reply matters (e.g. 'https://example.com') — star means "anyone". window.addEventListener('message', fn) — receiver side — where event.origin is the browser's guarantee of who talked, event.data is their payload, and fn gets to decide whether either can be trusted. Exploit surface = the gap where a check was assumed but never written.