How to wait for iframe parent to be ready for a postMessage?

Viewed 307

How can I, from within an iframe, wait until I'm certain that my parent has registered its eventListener:message before attempting to window.parent.postMessage to it?

The below code seems like it's got a race condition, which (while it happens to work without the delay) I've kludged in the 1s delay before sending, to boost reliability.

// THIS CODE RUNS IN THE PARENT
window.addEventListener('message',event=>{
  if(event.data==window.localStorage.getItem('expected')||confirm(event.data)) {
    document.querySelector('form').submit();
  }
});
// THIS CODE RUNS IN THE IFRAME
setTimeout(()=>{
  window.parent.postMessage(document.body.innerText,window.location.origin);
},1000);

How could I implement this deterministically? I don't want to "just hope" that the code in the parent ran faster than any delays I've set — rather, I'd like to do away with this gross "safety delay" and just have code that's defined to work, rather than code that happens to work.

1 Answers

How about loading the iframe content AFTER the parent has registered its event listener?

window.addEventListener('message', event => { ... });
var iframe = document.querySelector("#iframe");
iframe.src = "/url-to-load-in-iframe";

This way you can be certain that event listener is in place, before the iframe starts sending messages.

Related