In the living version of the specification of HTML from the WHATWG, there is an API known as Cross-document messaging. This allows two documents, from the same or different domains, to send messages to one another. The API allows, for example, two documents embedded alongside one another in
iframes to exchange messages to coordinate behavior.
Although this is not how it is defined in the specification, consider that a message logically has a sender and zero or more receivers. In the design of a message-passing framework, there are (at least) two different ways to deliver messages:
- deliver the message to existing registered receivers and delete the message or
- deliver the message to all registered receivers and store that message for delivery to receivers that register in the future.
Obviously, 1 makes the most sense. To implement delivery method 2 would mean that a single sender transmitting a high rate of messages could cripple the delivery system by forcing it to store every sent message for potential future delivery.
The Cross-document message API implements 1. Therefore, it would make sense that if a receiver r wanted to hear a message sent by sender s, r must be registered before s sends a message. The HTML spec says that s calls
postMessage() to send a message and r calls
addEventHandler() to become a receiver.
However, that logical ordering is not always required to use the Cross-document messaging API! Don't believe me? Go to the executable version of the code below and click the
sendMessageAndSetHandler button! You'll find that, even though the listener registers after the message is sent, it still receives the sender's transmission!
How is this possible?
The listener registration takes place immediately but, as the specification says,
In other words, between the call to
setMessageHandler() in the example above, the browser does not actually transmit the message. Therefore, by the time the message is actually sent, the receiver will be listening!
Makes perfect sense, right?