[whatwg] postMessage feedback

Ian Hickson ian at hixie.ch
Thu Apr 24 16:49:56 PDT 2008

I've made postMessage asynchronous, and have made its second argument 
required, with a magic value "*" to allow messages to be sent to any page.

I haven't made the API support sending data structures other than strings. 
I haven't changed the target of the event, it's still the Document object. 
This is a little odd, though, would people rather I made it the <body> 
element with an auto-forward to the Window object, like the 'load' event 
and so forth? That would allow onmessage="" handles to be written.

I haven't introduced a new API for conversations yet, but at some future 
point I do intend to introduce something based on this spec:


I expect this will be introduced around the same time that worker threads 
are introduced, probably based on this spec:


On Thu, 14 Feb 2008, Aaron Boodman wrote:
> On Tue, Feb 12, 2008 at 4:57 PM, Ian Hickson <ian at hixie.ch> wrote:
> > This was originally how the DOM Storage API worked, but there was 
> > significant pushback on this, resulting in the current string-only 
> > approach. When I came to writing the postMessage API, I considered 
> > that feedback and decided not to bother even trying.
> I see. One difference between DOM Storage and postMessage is that with 
> DOM Storage at least you had name and value separated out. For 
> postMessage you just get a single value field.

Does that make much difference? Splitting a name from a value in a string 
is pretty trivial.

> > Passing booleans, numbers and strings is trivial using the current 
> > API. Passing arrays of booleans and numbers is trivial too.
> >
> > Passing objects, or arrays of strings, arrays, or objects, is more 
> > complex, but as you point out, it can be done using JSON libraries. 
> > Since it is likely that JSON will be supported natively by UAs in due 
> > course, it seems better to wait for that support rather than adding 
> > type support to postMessage().
> I've seen performance problems using JS-based JSON libraries with Gears 
> workers. In those cases, the developer had to revert to hacky custom 
> message formats where what he really wanted was to pass an object.

That makes sense, yes.

> Someday, all browsers will have fast JSON support built in, but that 
> will be awhile for IE. Gears could implement postMessage today, but 
> we've looked into implementing fast JSON support and it seems difficult 
> to do much better than you can do with script without access to the 
> script engine internals.

This is just a temporary problem, though.

> > It seems that most messages will consist either of simple strings, or 
> > of complex data structures (objects). Reconstructing JS objects is not 
> > a trivial operation; you have to worry about references into other 
> > parts of the structure, getters and setters that hang or throw or 
> > return infinite arrays, functions, members that aren't enumerable, 
> > etc. I'd rather not go down that rat hole with v1.
> You'll have these problems with JSON too though, right? Whatever the 
> rules are, we'll have to figure them out eventually.

Sure, but that's why my preference would be to just let the Web developers 
figure out their own protocols optimised for their needs.

On Sat, 1 Mar 2008, Jonas Sicking wrote:
> Seems like you're advocating requesting that browsers (IE) add one 
> feature (JSON postMessage) to make up for lack of another feature (built 
> in JSON)? Wouldn't it then be better to standardize a way to do JSON 
> since that could benefit many other features too, such as JSON in DOM 
> storage and JSON over XMLHttpRequest.

That's a pretty compelling argument too.

On Thu, 14 Feb 2008, Adam Barth wrote:
> On Thu, Feb 14, 2008 at 10:46 AM, Ian Hickson <ian at hixie.ch> wrote:
> > This problem exists today with postMessage() too. Do people think we
> > should go fully asynchronous?
> I had assumed it was asynchronous (and I think others might make the 
> same assumption) because the PostMessage API in Windows is asynchronous.  
> The synchronous version in the Windows API is called SendMessage.

Consistency with Win32 isn't a top priority. :-)

On Thu, 14 Feb 2008, Aaron Boodman wrote (about the endpoints idea):
> On Thu, Feb 14, 2008 at 10:46 AM, Ian Hickson <ian at hixie.ch> wrote:
> >  ...except that the receiver could be extended to expect messages back:
> >
> >    // receiver
> >    window.addEventListener("message", function(e) {
> >      alert("got message: " + e.message);
> >      e.endPoint.onmessage = function (e) {
> >        alert("got a specific message: " + e.message);
> >      };
> >      e.endPoint.postMessage("good day");
> >    });
> Cool idea. I think it would be more intuitive if you didn't have to 
> create and send pipes explicitly and they were just the return value 
> from sendMessage(). However this prevents the type of mediation that you 
> describe in the top of your proposal.

Right, that kind of mediation is part of the point. :-)

On Thu, 21 Feb 2008, Sunava Dutta wrote:
> This is a compelling feature and will greatly ease developer pains 
> around cross frame communication hacks. -:)
> * The language in 
> http://www.whatwg.org/specs/web-apps/current-work/multipage/section-crossDocumentMessages.html 
> overpromises the security of this feature and we recommend a revision. 
> The current language implies that cross site scripting attacks are not 
> possible. This is not correct since a developer can receive script from 
> a postmessage and run it in the DOM.

Sure, but then the developer could also simply execute any markup passed 
through the query parameter of the page, or typed in by some random user. 
That's not a security flaw in the platform, it's a security flaw in the 
page. If we start listing the ways authors can shoot themselves in the 
foot, the spec is going to baloon in size.

> * For the postMessage (message, origin) method we would recommend the 
> parameter be called postMessage(message, targetOrigin) since it's easier 
> to understand what it is.


On Thu, 6 Mar 2008, Jeff Walden wrote:
> First, most of the problems you'll likely encounter relate to the value 
> of .origin for IDN origins.  HTML5 is silent on whether the value should 
> be IDN, punycode, or even a chimeric mixture.  I think .origin should 
> never be punycode (authors shouldn't be forced to know about punycode, 
> allowing either would require multiple origin comparisons, and also, 
> Unicode > ASCII), and the tests expect that (or, for the places where we 
> fail that, they expect the opposite and mark that situation as a 
> "todo").  If you do anything other than exactly match Mozilla behavior, 
> you'll see tests listed as failures.

This is an open issue in the spec. I've noted your opinion that it should 
be unicode.

On Mon, 10 Mar 2008, Anne van Kesteren wrote:
> Both HTMLElement and Window have an onmessage event handler attribute, 
> but HTMLDocument does not. And HTMLDocument is the event target in case 
> of cross-document messaging.
> I'm not sure if it's still fixable, but I wanted to ask if Document is 
> really the most consistent event target for this event. The 
> online/offline events in theory use the <body> element for instance (and 
> in practice Window).

This entire area is a mess. I'm not sure what to do about it. I've noted 
it, though.

On Wed, 2 Apr 2008, Thomas Roessler wrote:
> The postMessage API currently has no facility for passing structured 
> data of any kind between documents. It does not require prophetic skills 
> to predict that we'll soon see this API combined with JSON to get around 
> this limitation, and that we'll see the dreaded eval used to parse the 
> strings that are transmitted, causing another round of browser-based 
> cross site vulnerabilities.
> I would therefore propose that the HTML WG investigate extending 
> postMessage in order to enable programmatically simple *and* safe 
> passing of structured data.

The idea is that browsers should provide native JSON APIs, so that we 
don't have to make them postMessage-specific.

On Fri, 4 Apr 2008, Eric Seidel wrote:
> postMessage() is currently specified as a synchronous API -- the caller 
> is blocked until the target frame finishes handling the event.
> This seems broken to me.  I would argue this should be an asynchronous 
> API, for two reasons:
> 1.  JS content authors will want an async API.

I'm not convinced this is true.

> 2.  JS engine implementors will want an async API.  Major JS engines, 
> like SpiderMonkey (Mozilla) and JavaScriptCore (WebKit) can already be 
> used from multiple threads, but these browsers currently run all JS on 
> the main thread.  I would rather we didn't prevent FireFox or Safari 
> from some day running a separate interpreter (and thread) per tab. (Only 
> possible for frames which are not of the same origin.  Same-origin 
> frames already assume they can grab at each others innards in a 
> synchronous manner.)  postMessage imposes a NEW requirement that all 
> connected frames to be run from the same thread (or somehow synchronize 
> the threads after the first postMessage() call is made).  This 
> requirement would seem even worse for Microsoft, since IE8 looks like 
> it's multi-process.  A synchronous postMessage would require IE8 to keep 
> all frames which have references to each other in the same process.

Indeed. This is a pretty serious issue. In order to not prevent future 
extension of the platform in this area, and in order to allow Microsoft to 
implement postMessage() cross-tab in IE8 today, I have changed it to be 

On Fri, 4 Apr 2008, Anne van Kesteren wrote:
> It doesn't make sense to change this given that all synthesized event 
> dispatching is synchronous. I don't think postMessage() should be 
> different.

dispatchEvent() doesn't go cross-origin, though.

On Fri, 4 Apr 2008, Jeff Walden wrote:
> > 
> > (Only possible for frames which are not of the same origin.  
> > Same-origin frames already assume they can grab at each others innards 
> > in a synchronous manner.)  postMessage imposes a NEW requirement that 
> > all connected frames to be run from the same thread (or somehow 
> > synchronize the threads after the first postMessage() call is made).
> Wrong; if a window can get a reference to another window, same-origin or 
> not, run-to-completion already requires synchronous behavior. If some 
> piece of JS is in flight, every client-side change it can detect *must* 
> be one it has caused.

What change can you cause to another Window that couldn't be buffered and 
wait until that Window had finished running script? The only thing I can 
think of that you can do is navigate the window, and that's instrinsically 
asynchronous already.

On Sun, 6 Apr 2008, Aaron Boodman wrote:
> But I think the fact that messageEvent.source can be navigated and still 
> be the "source" is real issue here. To me, messages sent to 
> messageEvent.source after it has been unloaded should throw. I realize 
> this means that it cannot be the same object as is accessible via 
> window.frames[], but that seems OK to me. Actually, that is exactly what 
> hixie's messages proposal [1] does in this case.

I think we can work around this without introducing new objects just by 
using the targetOrigin parameter. No?

On Tue, 15 Apr 2008, Maciej Stachowiak wrote:
> I think async is better, for the following reasons:
> - PostMessage seems to imply a message queue model.
> - Processing a reply synchronously is awkward in any case, since you need a
> callback.
> - This is different from event dispatch because replies are expected to be
> common; two way communication channels like postMessage make more sense as
> asynchronous, while event dispatch is typically one-way.
> - Saying that runaway two-way messaging should be handled by a "slow script"
> dialog seems weak to me, compared to making the mechanism intrinsically
> resistant to runaway behavior.
> - Making new communication APIs async makes it more practical to partition
> browsing contexts into separate threads, processes, operation queues, or other
> concurrency mechanisms (within the limitations of what kind of things must be
> serialized.
> - We can foresee that workers in the style of Gears will be a future use case
> for postMessage; in that case, it clearly must be async.

These are pretty compelling reasons.

On Wed, 16 Apr 2008, João Eiras wrote:
> There are use cases for both sync and async API, so we should support 
> both. We could have either a new parameter for postMessage, like with 
> have for XHR, which defines the behavior (if async or not), or we could 
> have two functions postMessage asynchronous and sendMessage synchronous. 
> Then everyone would be happy.

This wouldn't resolve the problems with synchronous APIs raised earlier.

On Tue, 22 Apr 2008, Sunava Dutta wrote:
> I agree with Jonas. The spec needs to call out the behavior here. 
> Leaving it undefined will confuse developers. There are a few concerns 
> on cross process boundary/tab communication with sync since it 'couples' 
> entities across tabs/instances of the browser so that if one hangs the 
> other one will be taken down as well. On the other hand, the cross frame 
> messaging technique with the fragment today does not provide a way to do 
> this and our current synchronous implementation of cross document 
> messaging provides parity. Not to mention it's difficult for us to 
> change our implementation at this stage. I'm a bit swamped right now and 
> can't provide our team-wide stance on this just yet. In the absence of 
> current guidance in the spec I'd like to talk to my team further on the 
> cross tab/instance messaging scenario and the sync/async model.

I understand that it would be difficult to change implementations at this 
stage, but it seems like it would be in IE8's best interests to be able to 
support postMessage() regardless of whether the target frame is in the 
same process or not. Certainly I would expect authors to be annoyed if it 
suddenly stopped working just because the browser decided to use another 
process for the target tab! :-)

I've snipped many very good and useful arguments debating the pros and 
cons of sync vs async, which I took into account but don't really have 
much to add to. There are good arguments on both sides. The argument that 
seems most compelling, though, is that a synchronous API blocks an avenue 
of future development for the Web, whereas asynchronous APIs don't.

On Tue, 22 Apr 2008, Jeff Walden wrote:
> Make the targetOrigin argument non-optional.  "*" would mean "don't 
> care" while anything else would specify an origin (or result in a syntax 
> error).  If this is done, it's no longer possible to have 
> time-of-check/time-of-use issues (in the async case) without the web 
> developer explicitly choosing to do so.  This change shouldn't be any 
> more than 5-10 lines, and fixing existing testcases to adjust for this 
> change is straightforward.


Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

More information about the whatwg mailing list