Firefox 3.5/Firebug XMLHttpRequest and readystatechange bug
Last Thursday I was debugging an issue at work that was reported by two colleagues using Firefox 3.5. Initially, they had neglected to mention their fast upgrade to the latest Firefox and I spent some time fruitlessly trying to reproduce the issue. The complaint was that our page wasn’t displaying an Ajax response even though Firebug clearly showed that a response had been received. After checking my code, the rest of the page’s code, and debugging back into the YUI layer, I discovered that the source of the bug wasn’t JavaScript code at all – it was the browser. I thought I had found a bug in Firefox 3.5.
As I was debugging, I tweeted about this issue a handful of times and then pinged YUI Connection Manager creator Thomas Sha to see if he had heard of this issue. He hadn’t, so I continued digging and eventually found two bugs, one in the Firefox queue via my co-worker Steve Carlson and one in the Firebug queue via Christopher Blum. Christopher pointed out to me that he believed the cause of the issue was actually Firebug rather than Firefox itself. It’s now a week later and the issue hasn’t been resolved, so I’d like to share with everyone in the hopes of avoiding a lot of debugging by web developers around the world.
Symptoms
The issue presents itself when using Firefox 3.5 with Firebug 1.4.x or 1.5.x. The primary symptom is that the readystatechange event on an XMLHttpRequest object doesn’t get fired past readyState 1, meaning that any script listening for readystatechange to test for readyState being equal to 4 will fail silently. There is no JavaScript error to catch and no error condition to look for, and in fact, the response is received by the browser (as can be tested using the Firebug Net panel or Fiddler).
Fortunately, this doesn’t happen for all XHR communication. It seemingly occurs randomly but it’s likelihood increases as the amount of time it takes for a response to be fully received increases. Therefore, a request that receives a response in less than a second is far less likely to see this happen than a request that receives a response in ten seconds. The longer the response takes to return, the more frequently the readystatechange event will not fire. Kyle Huey created a reproducible test case that allows you to specify how long the server should wait before finishing the response. I’ve found I get the most consistent results using a value of 10 or higher (though I’ve experienced the same issue with responses taking less than a second as well).
The bad news is that there’s no way to detect that this issue is occurring. The good news is that there are workarounds.
Workarounds
Even though the readystatechange event isn’t firing, the readyState property is actually getting updated. So, it is possible to poll for changes in readyState on your own to determine when to determine that the response has been received. This is the approach taken in the YUI 2.7 Connection Manager, so if you’re using this utility, your code should continue to work without incident (the YUI 3 Beta 1 equivalent uses onreadystatechange, so users of that will be affected).
If that approach seems too hacky for you, there is another workaround. The Firefox XMLHttpRequest object supports the W3C Progress Events, all of which continue to work appropriately. The progress events are:
load– fires when a response is received from the server.error– fires when a network error occurs.abort– fires when the request has been aborted.progress– fires when a partial amount of data is available from the response.
Of these four, one of the first three will always be fired once a request is deemed to have been completed (by completion, I mean the connection is no longer open). Since readystatechange continues to work in all other browsers, you may need a temporary fork in your code to make use of the progress events in the meantime, such as:
var xhr = new XMLHttpRequest();
if (firefox3_5){
xhr.onload = xhr.onerror = xhr.onabort = function(){
processResponse(xhr);
};
} else {
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
processResponse(xhr);
}
};
}
xhr.open("get", "/url", true);
xhr.send(null);
Normally, I wouldn’t recommend browser-specific hacks, but in this case we’re not sure how long the issue will be out there and therefore don’t know how long our code will continue to break. At least this workaround will continue to work even after this issue has been addressed.
Ongoing investigation
The discussion of this issue has bounced back and forth between the Firebug team and the Firefox team as the two groups try to figure out the cause of the issue. I’ve personally been in touch with Rob Campbell of the Firebug team who is very dedicated to resolving this bug. I’ve also done a fair amount of investigation (within the realm of my knowledge) to try to help narrow down the issue. Some of the things I’ve found:
- Occurs with Firefox 3.5 and Firebug 1.4.x or 1.5.x, including the nightlies.
- Does not occur in Firefox 3.0 using Firebug 1.4.x.
- Does not occur in Firefox 3.5 without Firebug installed.
- Occurs more frequently as the response time of an Ajax request increases.
- Can cause an error to be output in the Firebug console in the format of:
onreadystatechange FAILS Error: Permission denied for to create wrapper for object of class UnnamedClass Error: Permission denied for to create wrapper for object of class UnnamedClass
[xpconnect wrapped nsIDOMEventListener]
Without much knowledge of how Firefox or Firebug work internally, my own conclusion is that a change in Firefox 3.5′s handling of XHR traffic probably breaks the way that Firebug is hooking into it. Since the same Firebug version (1.4.x) works on Firefox 3.0 without issue, that points the finger at Firefox. Of course, it’s entirely possible that Firebug is doing something that it shouldn’t be doing, in which case the finger is back at Firebug. And this is why the issue is so hard to track down.
If your responses are being returned in a small amount of time, then you’ll likely not run into this issue. This really affects those applications using Comet-style communication (such as Facebook chat) and requests being made over high-latency connections (spotty wireless networks, overseas servers). The latter is what I was working on when this issue first came to my attention.
The discussion continues on the Firefox bug and the Firebug bug. These are the two places to go for updates to the problem. I’d like to ask that you only comment on either bug if you have new information to add. It’s not going to help to have a lot of “me too” or “hurry up” comments. I know this is frustrating, as it’s akin to saying, “what if we remove the XMLHttpRequest object?” Both teams are taking this issue seriously and hope to have a resolution soon.
Update (14 July 2009): It looks like this issue is related to a security change in Firefox 3.5 that Firebug is running into. The way that Firebug tries to listen on an XHR object to get the response causes a security error and therefore the readystatechange event becomes useless. It’s believed that this bug is the ultimate source of the problem and will likely involve a Firefox patch to get resolution.
Update (18 July 2009): Firefox 3.5.1 does not fix this issue. Resolution still pending.
Update (23 July 2009): Firebug 1.4.1 and Firebug 1.5a18 fix this issue. Thanks to the folks on the Firebug team for their diligence.
Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O'Reilly Publishing, or anyone else. I speak only for myself, not for them.
Both comments and pings are currently closed.




26 Comments
Nice find and explanation. Although I haven’t ran into this issue yet, i can only imagine the headaches some developers will have with debugging this issue.
John Ryding on July 9th, 2009 at 10:43 pm
Yesterday I ran into this problem too. In a callback function after a XHrequest I tried to append a new childnode. [node].appendChild(n). due to an stupid mistake ‘n’ was NULL, and I got this strange readystatechange error in firebug. (FX 3.5 with Firebug 1.4.0b7)
J.S. on July 10th, 2009 at 5:16 am
I also faced this problem, but with firebug disabled everything seems to be OK.
razvantim on July 11th, 2009 at 5:01 am
I ran into this issue and was pulling out my hair until I found this article.
thanks!! I’ll make sure to pass around the link.
Anthony Gentile on July 13th, 2009 at 11:41 am
Nice findings… saved my time too
Muthu on July 15th, 2009 at 12:07 am
Just to say thanks for saving me a lot of time, because I just run into this problem.
Björn on July 15th, 2009 at 7:54 am
Thanks!
I was scared I had a devious bug in my code until I found this.
Nick on July 17th, 2009 at 12:56 am
Thanks for the info. I ran into this problem as well.
Bob Flavin on July 17th, 2009 at 9:36 am
We faced this issue too. I hope it will be solved ASAP. thanks for this bug reporting and solving hours of checking the source.
Irinel Bucur on July 17th, 2009 at 10:33 am
I know this doesn’t fix the bug, nor does it fix your user’s problems, but it helps if you disable Show XMLHttpRequests the pages load with no problems. Hopefully this works until Firebug releases an update.
jaime on July 17th, 2009 at 2:14 pm
[...] http://www.nczonline.net/blog/2009/07/09/firefox-35firebug-xmlhttprequest-and-readystatechange-bug/ http://www.ghastlyfop.com/blog/2007/01/onreadystate-changes-in-firefox.html [...]
Firefox 3.5 Fails - Bug With Ajax Callback Onreadystatechange on July 17th, 2009 at 3:11 pm
I think another workaround is to disable the cache. I haven’t seen this error until I’ve enabled cache for several testings on a current project. I use the function within the “Web Developer-Toolbar”…
Klaus M. Brantl on July 21st, 2009 at 2:36 am
@James/Klaus – these are both solutions that help you as the developer but do nothing to help your users. If any of your users have Firebug installed, they’ll see the issue and likely report an issue. That’s why I recommend using the workaround mentioned in this post as opposed to turning things on/off in Firefox or Firebug.
Nicholas C. Zakas on July 21st, 2009 at 2:16 pm
i ran into this problem too.
thank u so much for tracking the issue all the way!
flea papa on July 22nd, 2009 at 12:22 am
Especially, when the request is sent in synchronous mode, it doesn’t work at all.
xmlHttp = new XMLHttpRequest();
xmlHttp.open(“GET”, “http://xxx.xxxx.asp?….”, false); // send request synchronous mode
xmlHttp.onreadystatechange = handleHttpResponse; // register callback function
xmlHttp.send(“”); // send
alert(xmlHttp.responseText); // xmlHttp.responseText is empty.
function handleHttpResponse() {
if (xmlHttp.readyState == 4) {
alert(xmlHttp.responseText);
}
}
In case of above routine, the callback function(handleHttpResponse) is not called and responseText after the request is sent is empty.
Sunku Kang on July 22nd, 2009 at 2:36 am
This issue is fixed in Firebug 1.5a18, http://getfirebug.com/releases/
johnjbarton on July 22nd, 2009 at 11:32 pm
Looks like it is fixed now in Firebug 1.5a18
http://code.google.com/p/fbug/issues/detail?id=1948
Sebastian on July 23rd, 2009 at 8:04 am
thanx for proving ma code wasnt bad!!
is der a fix yet!!??
master on July 23rd, 2009 at 10:10 am
Excellent article. Thank you.
jon-e on July 23rd, 2009 at 11:33 am
Thank you so much, I had been debugging this for a while before finding this article! It’s exactly what I needed to know!
ihavenoname on July 24th, 2009 at 10:00 am
Goodness. I spent all afternoon debugging and getting nowhere until I found this post.
Thanks for sharing your experience.
Chris on July 26th, 2009 at 12:08 pm
[...] da imho keine Fehlermeldungen im Log. Nach ein bisschen Suchen bin ich auf dieses Blog gestossen: http://www.nczonline.net/blog/2009/07/09/firefox-35firebug-xmlhttprequest-and-readystatechange-bug/ Er hat die gleichen Probleme. Ausserdem wurden Bugtickets bei Firefox und Firebug eröffnet. Das [...]
deam.org » Blog Archive » onreadystatechange FAILS Error: Firefox 3.5.1 (3.5.0) und Firebug 1.4.0 on August 11th, 2009 at 7:15 am
I still seem to be having issues with ff v3.5.3 and firebug-1.5X.0a26.xpi
One novel approach i have used to “detect” firefox is by the capabilities of the XMLHttpRequest object
var xhr = new XMLHttpRequest();
if (typeof(xhr.onprogress)=='object'){
xhr.onload = xhr.onerror = xhr.onabort = function(){
processResponse(xhr);
};
} else {
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
processResponse(xhr);
}
};
}
xhr.open("get", "/url", true);
xhr.send(null);
This code has been tested in and works with ff 2.0.0.20, ff 3.5.3, ie 6.0, ie 7, Opera 10, Safari 3.2.1
mh on October 16th, 2009 at 7:43 am
Thanks so much for this article.
Was pulling my hair out until I read this.
Much appreciated.
Matt Evans on January 24th, 2010 at 7:29 pm
Problem is still there Firefox 3.6 and had nothing to do with Firebug. I actually went and installed Firebug to try and help debug the issue assuming it was some bug in my code before reading this article.
So far in my experience Firefox is hell to develop on. Chrome, Safari , even IE and Opera are far more predictable.
thomasmc on February 22nd, 2010 at 1:30 am
@thomasmc – The issue has been resolved. If you’re seeing other issues in Firefox 3.6, then it is unrelated to the issue mentioned in this post.
Nicholas C. Zakas on February 23rd, 2010 at 2:58 pm
Comments are automatically closed after 14 days.