Re: [whatwg] using postMessage() to send to a newly-created window
I ran into this early last year when I was first investigating MessagePorts: http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-March/018893.html I dimly recall that the response I got off-list (via IRC?) was that this was expected behavior (the intended use for window.postMessage() is for communicating with child iframes, where you can register an onload handler to be notified when it's safe to post messages), but I agree that it would be worthwhile to explicitly state this somewhere in the spec. -atw On Mon, Dec 21, 2009 at 7:24 PM, Dirk Pranke wrote: > Hi all, > > In the course of testing something today, I attempted to create a > window and immediately post a message to it, and was surprised that it > didn't seem to work. > > E.g.: > > var w = window.open("http://x";); > w.postMessage("hello, world", "*"); > > w never got the message - this seemed to be consistent across Safari, > Chrome, and FF (all I had installed on my Mac at the time, so > apologies to Opera, IE, and anyone else I've left out). > > Is this supposed to work? If not, is there a reliable way for the the > source to know when it is safe to send a message to the target? The > only way I can think of is for the target to send a message back to > the source, which only works if the target can get a reference to the > source using window.opener, which may or may not be possible or > desirable ... > > If this isn't supposed to work, can we state this explicitly in the spec? > > -- dirk >
Re: [whatwg] using postMessage() to send to a newly-created window
The window doesn't open synchronously, so you should have to wait for http://x/ to load (or for its document to at least be created) before you can start communicating with it. Note: If you instead open "about:blank" you should be able to communicate with it synchronously since "about:blank" is loaded synchronously. It is special-cased. >From the newly opened window, you could try posting a message to its opener. The opener could then handle that event and use it as a signal to know that it can know begin communicating with the newly opened window. I haven't tested any of this ;-) -Darin On Mon, Dec 21, 2009 at 7:24 PM, Dirk Pranke wrote: > Hi all, > > In the course of testing something today, I attempted to create a > window and immediately post a message to it, and was surprised that it > didn't seem to work. > > E.g.: > > var w = window.open("http://x";); > w.postMessage("hello, world", "*"); > > w never got the message - this seemed to be consistent across Safari, > Chrome, and FF (all I had installed on my Mac at the time, so > apologies to Opera, IE, and anyone else I've left out). > > Is this supposed to work? If not, is there a reliable way for the the > source to know when it is safe to send a message to the target? The > only way I can think of is for the target to send a message back to > the source, which only works if the target can get a reference to the > source using window.opener, which may or may not be possible or > desirable ... > > If this isn't supposed to work, can we state this explicitly in the spec? > > -- dirk >
Re: [whatwg] using postMessage() to send to a newly-created window
On Tue, Jan 5, 2010 at 5:00 PM, Darin Fisher wrote: > The window doesn't open synchronously, so you should have to wait for > http://x/ to load (or for its document to at least be created) before you > can start communicating with it. > Note: If you instead open "about:blank" you should be able to communicate > with it synchronously since "about:blank" is loaded synchronously. It is > special-cased. > From the newly opened window, you could try posting a message to its opener. > The opener could then handle that event and use it as a signal to know that > it can know begin communicating with the newly opened window. > I haven't tested any of this ;-) This is a sort of suboptimal state of affairs though. Compare to workers, which also do not load synchronously, but which you can immediately send messages to using postMessage(). We could use a similar solution for windows postMessage as we use for worker postMessage. The main question is if that would break existing content. / Jonas
Re: [whatwg] using postMessage() to send to a newly-created window
On Tue, Jan 5, 2010 at 5:03 PM, Jonas Sicking wrote: > The main question is if that would break existing content. The existing content would be racy because postMessage returns to the main event loop before dispatching. It would at least make the content more predictable. :) Adam
Re: [whatwg] using postMessage() to send to a newly-created window
I understand the rationale, and the workaround you suggest does work, (I have tested it, in FF, Safari and Chrome). But, as Jonas mentioned, this isn't what we do with workers, and it feels counter-intuitive to me (I'm having trouble thinking of other async messaging models that require an application-level handshake like this before messaging can commence). Are there reasons other than implementation complexity (an okay reason) or backwards-compatibility (a better reason) not to have the post work in this case? Put differently, would anything break (other than a rather oddly written app that explicitly counted on this behavior) if this did work? As an alternative, would it be possible to create an onChildLoad() event in the parent so that the parent could reliably send a message without needing the child's cooperation? These seems only marginally better than having the child post to the parent, so it may not be worth it ... -- Dirk On Tue, Jan 5, 2010 at 5:00 PM, Darin Fisher wrote: > The window doesn't open synchronously, so you should have to wait for > http://x/ to load (or for its document to at least be created) before you > can start communicating with it. > Note: If you instead open "about:blank" you should be able to communicate > with it synchronously since "about:blank" is loaded synchronously. It is > special-cased. > From the newly opened window, you could try posting a message to its opener. > The opener could then handle that event and use it as a signal to know that > it can know begin communicating with the newly opened window. > I haven't tested any of this ;-) > -Darin > > On Mon, Dec 21, 2009 at 7:24 PM, Dirk Pranke wrote: >> >> Hi all, >> >> In the course of testing something today, I attempted to create a >> window and immediately post a message to it, and was surprised that it >> didn't seem to work. >> >> E.g.: >> >> var w = window.open("http://x";); >> w.postMessage("hello, world", "*"); >> >> w never got the message - this seemed to be consistent across Safari, >> Chrome, and FF (all I had installed on my Mac at the time, so >> apologies to Opera, IE, and anyone else I've left out). >> >> Is this supposed to work? If not, is there a reliable way for the the >> source to know when it is safe to send a message to the target? The >> only way I can think of is for the target to send a message back to >> the source, which only works if the target can get a reference to the >> source using window.opener, which may or may not be possible or >> desirable ... >> >> If this isn't supposed to work, can we state this explicitly in the spec? >> >> -- dirk > >
Re: [whatwg] using postMessage() to send to a newly-created window
It sounds tempting to say that the postMessage should be queued until the newly opened window is loaded, but what point in time is that exactly? Is that after the load event is dispatched on the newly opened window? Note: a newly opened window can begin communicating with its opener much earlier (via inline script execution). However, if we try to dispatch the postMessage events before the load event then the newly opened window may not have registered its event handlers yet. (A future
Re: [whatwg] using postMessage() to send to a newly-created window
On Tue, 05 Jan 2010 23:29:40 -0500, Dirk Pranke wrote: As an alternative, would it be possible to create an onChildLoad() event in the parent so that the parent could reliably send a message without needing the child's cooperation? These seems only marginally better than having the child post to the parent, so it may not be worth it ... In Firefox, you can do stuff like this: var w = window.open("handler.html"); w.addEventListener("DOMContentLoaded", function(e) { var targetWin = e.target.defaultView. targetWin.postMessage("Hello", "domain"); }, false); But, I think that only works in Firefox. In Opera at least, I'm sure it doesn't work. -- Michael
Re: [whatwg] using postMessage() to send to a newly-created window
On Tue, Jan 5, 2010 at 9:34 PM, Michael A. Puls II wrote: > On Tue, 05 Jan 2010 23:29:40 -0500, Dirk Pranke > wrote: > > As an alternative, would it be possible to create an onChildLoad() >> event in the parent so that the parent could reliably send a message >> without needing the child's cooperation? These seems only marginally >> better than having the child post to the parent, so it may not be >> worth it ... >> > > In Firefox, you can do stuff like this: > > var w = window.open("handler.html"); > w.addEventListener("DOMContentLoaded", function(e) { >var targetWin = e.target.defaultView. >targetWin.postMessage("Hello", "domain"); > }, false); > > But, I think that only works in Firefox. In Opera at least, I'm sure it > doesn't work. > > The same thing works fine in WebKit-based browsers as well. However, this solution only works when the newly opened document is in the same origin as the opener. -Darin
Re: [whatwg] using postMessage() to send to a newly-created window
On Wed, 06 Jan 2010 06:30:17 +0100, Darin Fisher wrote: I suspect the postMessage would be dispatched in this case, but the event dispatch would probably go to the document at http://a/ instead of http://b/. This would fail as well because of the targetOrigin argument. (Unless that is * I guess, but can't you just check before invoking postMessage() anyway?) -- Anne van Kesteren http://annevankesteren.nl/
Re: [whatwg] using postMessage() to send to a newly-created window
On Wed, Jan 6, 2010 at 1:11 AM, Anne van Kesteren wrote: > On Wed, 06 Jan 2010 06:30:17 +0100, Darin Fisher > wrote: > >> I suspect the postMessage would be dispatched in this case, but the event >> dispatch would probably go to the document at http://a/ instead of >> http://b/. >> > > This would fail as well because of the targetOrigin argument. (Unless that > is * I guess, but can't you just check before invoking postMessage() > anyway?) > > It was given as "*" in the example. -Darin
Re: [whatwg] using postMessage() to send to a newly-created window
On Mon, 21 Dec 2009, Dirk Pranke wrote: > > In the course of testing something today, I attempted to create a window > and immediately post a message to it, and was surprised that it didn't > seem to work. > > E.g.: > > var w = window.open("http://x";); > w.postMessage("hello, world", "*"); > > w never got the message - this seemed to be consistent across Safari, > Chrome, and FF (all I had installed on my Mac at the time, so > apologies to Opera, IE, and anyone else I've left out). It got the message, it just got it when the window's document was about:blank and before the scripts in that window were ready to receive any messages. > Is this supposed to work? If not, is there a reliable way for the the > source to know when it is safe to send a message to the target? If it's same-origin, the simplest solution is to wait for onload. If it's cross-origin, there is by design no mechanism to expose when the page is ready short of the other site announcing it (by sending a message to its opener, in this case). > If this isn't supposed to work, can we state this explicitly in the > spec? Where would you like it mentioned and what would you like it to say? On Tue, 5 Jan 2010, Jonas Sicking wrote: > > This is a sort of suboptimal state of affairs though. Compare to > workers, which also do not load synchronously, but which you can > immediately send messages to using postMessage(). > > We could use a similar solution for windows postMessage as we use for > worker postMessage. I assume you mean provide a mechanism by which messages are queued until the page does something that causes the events to be fired? We could, but it wouldn't actually help in this particular case (since the first message is sent to the about:blank document, and I presume we would nuke all pending messages upon navigation). It seems relatively easy to work around the problem in the case of windows (just send a message when you're ready), so I'm not sure it's worth it. On Tue, 5 Jan 2010, Adam Barth wrote: > > The existing content would be racy because postMessage returns to the > main event loop before dispatching. It would at least make the content > more predictable. :) Only content that tries to communicate to a document while it's loading. How common is that likely to be? In the usual case, scripts only run after onload, and the iframes delay onload. The risk is that anyone using addEventListener() would never get the message. On Tue, 5 Jan 2010, Dirk Pranke wrote: > > I understand the rationale, and the workaround you suggest does work, (I > have tested it, in FF, Safari and Chrome). But, as Jonas mentioned, this > isn't what we do with workers, and it feels counter-intuitive to me (I'm > having trouble thinking of other async messaging models that require an > application-level handshake like this before messaging can commence). > Are there reasons other than implementation complexity (an okay reason) > or backwards-compatibility (a better reason) not to have the post work > in this case? Put differently, would anything break (other than a rather > oddly written app that explicitly counted on this behavior) if this did > work? If we changed it, it would be multiple years before IE changed to match. Is it worth having IE be non-compliant for that long, rather than having interoperability for that long, given that this is basically an edge case and quite managable? > As an alternative, would it be possible to create an onChildLoad() event > in the parent so that the parent could reliably send a message without > needing the child's cooperation? These seems only marginally better than > having the child post to the parent, so it may not be worth it ... For iframes, onload does that. For same-origin content, onload on the target does that. For cross-origin cross-window content, not exposing this is by design. On Tue, 5 Jan 2010, Darin Fisher wrote: > > It sounds tempting to say that the postMessage should be queued until > the newly opened window is loaded, but what point in time is that > exactly? Is that after the load event is dispatched on the newly opened > window? > > Note: a newly opened window can begin communicating with its opener much > earlier (via inline script execution). > > However, if we try to dispatch the postMessage events before the load > event then the newly opened window may not have registered its event > handlers yet. (A future
Re: [whatwg] using postMessage() to send to a newly-created window
Sorry for the delay in replying ... On Thu, Mar 25, 2010 at 1:31 AM, Ian Hickson wrote: > On Mon, 21 Dec 2009, Dirk Pranke wrote: >> >> In the course of testing something today, I attempted to create a window >> and immediately post a message to it, and was surprised that it didn't >> seem to work. >> >> E.g.: >> >> var w = window.open("http://x";); >> w.postMessage("hello, world", "*"); >> >> w never got the message - this seemed to be consistent across Safari, >> Chrome, and FF (all I had installed on my Mac at the time, so >> apologies to Opera, IE, and anyone else I've left out). > > It got the message, it just got it when the window's document was > about:blank and before the scripts in that window were ready to receive > any messages. > > >> Is this supposed to work? If not, is there a reliable way for the the >> source to know when it is safe to send a message to the target? > > If it's same-origin, the simplest solution is to wait for onload. > > If it's cross-origin, there is by design no mechanism to expose when the > page is ready short of the other site announcing it (by sending a message > to its opener, in this case). > > >> If this isn't supposed to work, can we state this explicitly in the >> spec? > > Where would you like it mentioned and what would you like it to say? > How about putting some text at the end of Section 9.2.3, "Posting Messages" that says something like: "Note that messages are not guaranteed to be delivered reliably under all circumstances. User agents are allowed to not deliver messages if the details of their implementation may make this difficult or impossible to do safely and securely. For example, if a new child window is created and then a message is immediately posted to it, that message may not get delivered, even if the child window belongs to the same origin. A rationale for this may me that it would require the user agent to queue the message across creation of a new event loop, leading to all sorts of unpredictable timing issues." I'm not particularly happy with the wording here, but it gets the point across. Of course, putting in text like this would naturally lead the reader to wonder under what conditions messages *are* guaranteed to be delivered reliably. Which is, I think, a valid question I don't know the answer to. Is it safe to say that messages are delivered reliably if the destination window belongs to the specified targetOrigin and the destination window is fully loaded? What if a navigation event is triggered on the destination window? -- Dirk
Re: [whatwg] using postMessage() to send to a newly-created window
On Tue, 6 Apr 2010, Dirk Pranke wrote: > > How about putting some text at the end of Section 9.2.3, "Posting > Messages" that says something like: > > "Note that messages are not guaranteed to be delivered reliably under > all circumstances. User agents are allowed to not deliver messages if > the details of their implementation may make this difficult or > impossible to do safely and securely. For example, if a new child window > is created and then a message is immediately posted to it, that message > may not get delivered, even if the child window belongs to the same > origin. A rationale for this may me that it would require the user agent > to queue the message across creation of a new event loop, leading to all > sorts of unpredictable timing issues." > > I'm not particularly happy with the wording here, but it gets the point > across. Of course, putting in text like this would naturally lead the > reader to wonder under what conditions messages *are* guaranteed to be > delivered reliably. Which is, I think, a valid question I don't know the > answer to. Is it safe to say that messages are delivered reliably if the > destination window belongs to the specified targetOrigin and the > destination window is fully loaded? What if a navigation event is > triggered on the destination window? I've added a note explaining the problem, but it doesn't say what the above note says. This has nothing to do with UA limitations -- it's inherent in the platform. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'