3/30/2006

Reusing XMLHttpRequest Object in IE

I came across an article posted by Eric (Coauthor of Ajax In Action) which talks about reusing XMLHttpRequest object. I read many blogs and message boards where similar kind of problem was faced by many users. But frankly speaking I never faced this problem before, except in the example given by Eric in his blog. That made me think why I am able to reuse the same XMLHttpRequest object while others not. So, I decided to write this short article on reusing XMLHttpRequest object in IE.

In the current project I am doing, I implemented AJAX technique and using one instance (yes, you heard it right, only one instance) of XMLHttpRequest object without abort calls and I use IE 6, XP SP2. There is one little trick that you have to use to reuse one instance. I'll take the same example developed by the author in the blog Reusing XMLHtpRequest - dilema and show you how to reuse XMLHttpRequest object.

The code developed in the article uses the javascript statements

req_fail_IE.onreadystatechange = processReqChange_fail_IE;
req_fail_IE.open("GET", url, true);
req_fail_IE.send("");

where it assigns the callback handler to the XMLHttpRequest, open the request and send the request which actually transmits the request.

Instead of this piece of code, just try using the following code and it will do the trick. Believe me and it's worth trying.

req_fail_IE.open("GET", url, true);
req_fail_IE.onreadystatechange = processReqChange_fail_IE; //changed the position of callback handler
req_fail_IE.send("");


I worked on two examples. One that is originally created by Eric,
http://www.geocities.com/keelypavan/Non_Working.html .
and the code I changed (just changed whatever I mentioned above and nothing else, that's why you still see button names as "bad-test1" and "bad-test2", but don't care, both buttons still work even if they are named "bad"). http://www.geocities.com/keelypavan/working.html .
Note: Please bear with those Yahoo geocities ads and if you have pop-up blocker, you may get Javascript errors and these errors are from geocities ads code, please ignore them.

One more important point that I observed is, the request is getting fired even in the first example for the second button, which is not showing up any alert, but the callback handler is not getting called. So, it has to do with assigning callback handler to the XMLHttpRequest's onreadystatechange.

If it doesn't work, please let me know, because I only tested in IE 6, Mozilla Firefox 1.0.7 and no other versions.

Have a great reuse of XMLHttpRequest object and stop memory leaks ( update: I haven't demonstarted this piece).

Update on April 2nd, '06:
I recently got an email from Michael Mahemoff (Author of Ajax Design Patterns and maintaining the site www.ajaxpatterns.org ) about not using abort. His question in his own words:

Michael Mahemoff: What's actually the advantage of not calling abort()? If the call is stuck in state 2 or 3 waiting for a response, wouldn't you want to call abort() anyway?

Pavan Keely:
No, I wouldn’t want to. Because browser is intelligent enough to see whether to proceed with the request furthur or not when I issue one more call on the same XHR object. If one request is being processed on one instance of XHR object and if the application issues one more call on the same XHR, browser will abort the first request and proceeds with the second request. This is not just theoritical analysis but I did few testings too in IE6 which favor my analysis.

For demonstration purposes, I created one example which creates a XHR object when loading and issues 5 requests immediately one after the other in a loop upon a click of "Get Data" button. If you have any TCP probe tools like HTTPWatch or anything like that, please see the requests being fired from the browser. Except for the last call, all previous 4 calls will be "abort"ed. ( There is a basic free version of HTTPwatch available if you don't have one.).

link to the example: http://www.geocities.com/keelypavan/Request_abort_test.html

Probably, this is one of the best practices to call open before setting onreadystatechange and may be calling abort if the request is in process.