Julian Jelfs’ Blog

Interrupted XmlHttpRequests cause IE to hang

Posted in Javascript by julianjelfs on May 6, 2009

I ran into a problem using MS Ajax script services recently. I was getting reports of intermittent hanging in IE (6 and 7) with some newly developed pages. I had a vague feeling it was something to do with the Script Services and a quick search revealed that this is a relatively well known problem.

As described in one of the responses to that question, the issues is caused when a page closes after an asynchronous ajax request is started but before it completes. In this scenario one of the browser’s available connections (of which it has 2 by default) is tied up and not released. So if this happens a couple of times, the browser has no available connections to service normal requests and appears to hang.

The solution is to abort any pending XmlHttpRequest when the page unloads. It’s not totally obvious how to do this when you are using Script Services with the generated proxy, because the actual XmlHttpRequest object itself is buried in multiple layers of magic. After a bit of digging I came up with the following solution:

$(function(){
    var pending = null;
    Sys.Net.WebRequestManager.add_invokingRequest(function(executor, args){
        pending = args.get_webRequest().get_executor();
    });

    Sys.Net.WebRequestManager.add_completedRequest(function(executor, args){
        pending = null;
    });

    $(window).unload(function(){
        if(pending!==null){
            pending.abort();
        }
    });
});

So what this does is just track the executor of the currently executing web request and set it to null when the request completes. On unload, we check if there are any pending request executors, and if there are we call abort on them. This prevents the hanging issue for me in IE which is a big relief.

Obviously this mechanism may not be adequate for you if ajax calls are not queued because there may be more than one pending request. In my case, all service calls are channelled through a queue so that can’t happen. Otherwise you would have to implement some mechanism to correlate the invoked request with the completed request.

Advertisements
Tagged with: ,

4 Responses

Subscribe to comments with RSS.

  1. rorkAdjourn said, on December 11, 2009 at 3:41 pm

    Cool story, I didn’t thought it was going to be so stunning when I looked at the url!!

  2. David Ellis said, on March 3, 2010 at 2:55 pm

    Presumably the same issue might arise using Dojo ajax requests in IE?

    • julianjelfs said, on March 3, 2010 at 8:22 pm

      Hi Dave!, presumably yes. The problem seems to lie with IE rather than with the MS Ajax implementation so I’m sure it could equally apply to any script library. It seems like you should not have too much of a problem tracking on page unload if there is an outstanding request. The problem I can foresee may be gaining access to the XmlHttpRequest object itself in order to abort it. I know that with jQuery things that are internal like that are kept private by wrapping the whole thing in closures (yes you can do private in javascript!). This means that the only way to get at it would be from the inside i.e. by extending jQuery. So we were lucky to be using MS Ajax for most of our ajax stuff which allows a relatively easy way to abort.

      Good luck.

  3. David Ellis said, on March 5, 2010 at 12:17 pm

    Thanks Julian. I have been doing quite a lot of Dojo recently, including some Ajax calls. We haven’t come across this issue but I guess potentially we might.

    I see some articles discussing how to cancel a Dojo Ajax request.

    http://o.dojotoolkit.org/forum/dojo-core-dojo-0-9/dojo-core-support/how-do-i-abort-ajax-request

    Dojox.Gfx is quite a nice graphics library and I’ve done some quite fun stuff with that.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: