Search code examples
javascriptxmlhttprequest

XMLHttpRequest timeout case - onreadystatechange executes before ontimeout?


I am using XMLHttpRequest to make asynchronous GET requests. I have

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {//Handle only if the state has completed
        if (xhr.status === 200) {
            successHandler.call(context, xhr.responseText);
        } else {
            console.warn('onreadystatechange:' + new Date().getTime());
            failureHandler.call(context, xhr.status, xhr.statusText);
        }
    }
};
xhr.ontimeout = function () {
    console.warn('ontimeout: ' + new Date().getTime());
    failureHandler.call(context, 0, 'timeout');
};

I am forcing timeout using network throttling. I observe both onreadystatechange and ontimeout callbacks are called in case of timeouts, onreadystatechange preceding ontimeout. I was under the impression that only one of the two will be executed. I am using Chrome. Does anybody know if this is expected?


Solution

  • The modern solution is to use appropriate XMLHttpRequest events: onload and onerror if you want to handle these cases separately, onloadend if you wish to detect HTTP request completion regardless of success, and ontimeout for timeouts. When a timeout occurs, ontimeout is called, but not onloadend. onreadystatechange looks like it's best left to die quietly. The full set of events can be found here:

    http://www.w3.org/TR/XMLHttpRequest/#events

    Since the onreadystatechange→ontimeout sequence doesn't appear to afflict IE 8, for my purposes I'm happy to do the following: use onreadystatechange in IE 8, and onloadend in Firefox/modern MSIE (using the following test to see if the event is defined: if ("onloadend" in httpObj) ...).

    This is an internal system, so this suffices for me; for the OP, more testing may be required.