Roman
Roman

Reputation: 4611

IE8 hangs when more than 4 async XmlHttpRequests are triggered concurrently

for (var i = 0; i < 5; ++i) {
  var xhr;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    xhr = new ActiveXObject("Msxml2.XMLHTTP");
  }
  xhr.open('GET', '/Test/LongOperation?p=' + new Date());
  xhr.send('');
}

This is only a demo (not live code) but it illustrates the core problem. LongOperation is a method that returns a result after 10 seconds.

Questions:

  1. Why does IE8 (and maybe other IEs) hang when the user tries to navigate away from page right after the above code snippet has been executed? FireFox/Safari cancel these requests and allow navigation to another page. If you replace 'i < 5' with 'i < 4' then IE would not hang.

  2. How to work around this ugly IE behavior? Users are very upset when their browser suddenly hangs.

Upvotes: 3

Views: 4778

Answers (3)

Roman
Roman

Reputation: 4611

My answer to my question. I abort all not completed xhr objects in window.onbeforeunload. At least this solution works for me. I slightly override $.ajax() method behavior:

;(function($) {
    var rq = [];
    var ajax = $.ajax;
    $.ajax = function(settings) {
        // override complete() operation
        var complete = settings.complete;
        settings.complete = function(xhr) {
            if (xhr) {
                // xhr may be undefined, for example when downloading JavaScript
                for (var i = 0, len = rq.length; i < len; ++i) {
                    if (rq[i] == xhr) {
                        // drop completed xhr from list
                        rq.splice(i, 1);
                        break;
                    }
                }
            }
            // execute base
            if (complete) {
                complete.apply(this, arguments)
            }
        }

        var r = ajax.apply(this, arguments);
        if (r) {
            // r may be undefined, for example when downloading JavaScript
            rq.push(r);
        }
        return r;
    };

    // 'kill' all pending xhrs
    $(window).bind('beforeunload', function() {
        $.each(rq, function(i, xhr) {
            try {
                xhr.abort();
            } catch(e) {
                $debug.fail('failed to abort xhr');
            }
        });
        rq = [];
    });
})(jQuery);

$debug - my utility class

Upvotes: 2

Neil Trodden
Neil Trodden

Reputation: 4728

Try running them asynchronously and then triggering the next http request when the each completes. I suspect that the xmlhttp request is blocking the UI thread of IE whereas the implementations of that on other browsers is a little more graceful.

Hopefully that will give you a work-around for question 2 but I can only guess at the true reason for question 1, it could just be a bug.

Upvotes: 0

1800 INFORMATION
1800 INFORMATION

Reputation: 135375

Most browsers have an inbuilt limit of 4 connections to any given server. One way to work around this "problem" might be to use a different hostname for out of band XML requests - your user requests will go to the main hosts, while the AJAX requests can go to the second server.

Upvotes: 3

Related Questions