xdr-streaming connection closed on "javascript:;" in IE8
tomaszdurka opened this issue · 16 comments
We're having an issue with xdr-streaming transport under IE8 while using <a>
elements with href="javascript:;"
.
Reproduce steps:
- Download example: https://github.com/sockjs/sockjs-node/tree/master/examples/echo
- Run server, open
http://localhost:9999
- should work fine. - Add following code into index.html body:
<a href="javascript:;">Break connection</a>
- Reload page - Connection should be established and work normal
- Click newly added
<a>
element
Result: Connection is closed.
Actually any javascript: ...
code within href
attribute will break the connection. Is this known issue? We can workaround it, but would be great if we could keep those hrefs as they are right now.
Wow, IE will never stop amazing me. I can reproduce that in IE9. Frankly - I doubt there is a quick workaround. I guess that clicking on a
triggers some form of page reload mechanism, that cancels outgoing XDR requests. Only later IE realizes that there isn't a page refresh really.
The same seem to happen to 'iframe-xhr-polling' transport. I guess XDR / XHR just gets killed when user clicks on javascript:
link.
I'm not sure if we can do anything about it - sorry. Maybe try using onclick
on a
elements instead? Dirty workaround idea - jquery rule to match all a
elements and just execute the javascript code but from onclick handler?
There seems to be related SockJS bug - SockJS doesn't seem to trigger onclose
handler in this case, that looks wrong.
Thanks for quick reply.
We've checked iframe-htmlfile
transport. Seems to be the same problem.
We see the same problem when using Faye.
Only Socket.IO doesn't suffer from it, seems they work around it somehow.
cant reproduce with IE8 and with XDR
@tomaszdurka Socket.io uses flashsockets on IE by default, right? You're sure you're testing when it's on XHR/XDR transport?
Tests were based on socket.io chat example. We've tested both htmlfile
and xhr-polling
transports - both work fine.
@Yaffle Thanks, that was actually quite helpful.
@tomaszdurka Okay, it is SockJS misbehaviour. Quick fix: find this line in sockjs.js
and comment it out:
utils.attachEvent('beforeunload', unload_triggered);
Explanation: SockJS actively cleans up connections on page reload. This is in order to avoid memory leaks in some browsers (firefox is know to leak websocket objects, IE leaks pretty much everything). Apparently javascript:
links trigger onbeforeunload
event on window
. SockJS cleans up state on this event. Thus this bug.
The online demos use released SockJS version, so no, you can't test it
online. You need to get the compiled javascript from
http://cdn.sockjs.org/sockjs-0.3.js , modify as I instructed and use
that in your code, at least until I release new version.
Yes, we have commented that out and works for xdr-streaming
well. Thanks for this fast hotfix.
However even after commenting it out there is still the same issue for iframe-htmlfile
transport.
Thanks again.
Are you sure the iframe is using the modified sockjs.js file? You need to change that on the server side (see sockjs_url
option passed to sockjs-node).
You are absolutely right. Am quite new to SockJS and completely forgot about this property.
I wasn't aware it actually builds the iframe with this url as script source.
Confirmed - this fixes the issue for iframe-htmlfile
as well. Thanks, am looking forward for the release where this fix will come live then.
Hey Marek,
I was wondering if you are able to provide some permanent solution (fix) to this issue. Or the quirks listing is all you want or going to do.
I've been looking into the socket.io code and they seem to attach that onbeforeunload
event handler only if some conditions are met (CORS
and !XDomain
) - or when sync disconnect on unload
option is enabled.
https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js#L52
Maybe this can point some more flexible (to us) solution. If you not plan to implement any adjustments please let us know what is your reasoning.
Thanks,
Tomasz
Thanks for the socket.io link, interesting.
I think I'll drop attaching to onbeforeunload
at all. The main reason for using this event was due to quirkyness of opera iframes, AFAIR. I think it's fairly safe to drop this event in 99% of cases. I may write some special case for opera if it still is a problem (opera 12 was released recently), but I doubt it will manifest itself.
IE: I believe it's fairly safe to remove the line I suggested earlier.
Seems like this is close-able?