47

I'm looking on the web, but documentation is hard to come by. We all know the basic AJAX call using the browser's built-in XMLHttpRequest object (assume a modern browser here):

var xmlHttp = new XMLHttpRequest();  // Assumes native object

xmlHttp.open("GET", "http://www.example.com", false);

xmlHttp.send("");

var statusCode = xmlHttp.status;
// Process it, and I'd love to know if the request timed out

So, is there a way that I can detect that the AJAX call timed out by inspecting the XMLHttpRequest object in the browser? Would I be advised to do something like window.setTimeout(function() { xmlHttp.abort() }, 30000);?

Thanks!

-Mike

YakovL
  • 7,557
  • 12
  • 62
  • 102
Mike
  • 5,560
  • 12
  • 41
  • 52

2 Answers2

61

Some of the modern browsers (2012) do this without having to rely on setTimeout: it's included in the XMLHttpRequest. See answer https://stackoverflow.com/a/4958782/698168:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
        alert("ready state = 4");
    }
};

xhr.open("POST", "http://www.service.org/myService.svc/Method", true);
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
xhr.timeout = 4000;
xhr.ontimeout = function () { alert("Timed out!!!"); }
xhr.send(json);
Community
  • 1
  • 1
Julien Kronegg
  • 4,968
  • 1
  • 47
  • 60
  • 11
    In 2014, this answer should be tagged as the correct one. Nowadays, almost any browser supports this (even IE8 onwards). – Jose Gómez Oct 15 '14 at 22:13
  • 8
    Well, not quite - be warned that ontimeout event does not get fired until AFTER readyState == 4 is triggered. This is not only non-intuitive, but makes it difficult to create conditional behavior based on whether an upload didn't succeed due to the fact that there was a timeout or not. For example, customizing a user alert as to the reason an upload failed. In my situation I found that I could only accomplish what I wanted with setTimeout. Also, xhr.timeout does not seem to work on Safari as of 2016. – KevinHJ Jun 23 '16 at 01:03
  • In my case, part of a page is updated when the user changes any option in a form. For this I use the onclick and onchange events and an AJAX object. What I want is to display an alert when the network goes offline, so that users get feedback that their changes have not been saved. If I disconnect the network, the solution based on "setTimeout" works; the one based on "ontimeout" does not work. – Antonio Cañas Vargas May 19 '20 at 12:16
  • ontimeout was only added to Chrome in version 91. https://caniuse.com/?search=XmlHttpRequest.ontimeout Debian is only at version 90 as of now. – Peter Quiring Jun 23 '21 at 14:14
54

UPDATE: Here's an example of how you can handle a timeout:

var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "http://www.example.com", true);

xmlHttp.onreadystatechange=function(){
   if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
      clearTimeout(xmlHttpTimeout); 
      alert(xmlHttp.responseText);
   }
}
// Now that we're ready to handle the response, we can make the request
xmlHttp.send("");
// Timeout to abort in 5 seconds
var xmlHttpTimeout=setTimeout(ajaxTimeout,5000);
function ajaxTimeout(){
   xmlHttp.abort();
   alert("Request timed out");
}

In IE8, You can add a timeout event handler to the XMLHttpRequest object.

var xmlHttp = new XMLHttpRequest();
xmlHttp.ontimeout = function(){
  alert("request timed out");
}

I would recommend against making synchronous calls as your code implies and also recommend using a javascript framework to do this. jQuery is the most popular one. It makes your code more efficient, easier to maintain and cross-browser compatible.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Jose Basilio
  • 50,714
  • 13
  • 121
  • 117