Check out this snippet of my AJAX function:
/**
* This function initiates an AJAX request
*
* @param url The URL to call (located in the /ajax/ directory)
* @param data The data to send (will be serialized with JSON)
* @param callback The function to execute with the response text
* @param silent If true, errors will not be displayed to the user
* @param loader The element containing the message "Loading... Please wait"
*/
AJAX = function(url,data,callback,silent,loader) {
var a,
attempt = 0,
rsc = function() {
if( a.readyState == 4) {
if( a.status != 200) {
if( a.status > 999) { // Sometimes IE throws 12152 error
attempt++;
if( attempt < 5)
send();
else if( !silent) {
alert("HTTP Error "+a.status+" "+a.statusText+"<br />Failed to access "+url);
}
}
else if(!silent) {
alert("HTTP Error "+a.status+" "+a.statusText+"\nFailed to access "+url);
}
}
else {
callback(JSON.parse(a.responseText));
}
}
},
to = function() {
a.abort();
attempt++;
if( attempt < 5)
send();
else if( !silent) {
alert("Request Timeout\nFailed to access "+url);
}
};
data = JSON.stringify(data);
var send = function() {
if( loader && attempt != 0) {
loader.children[0].firstChild.nodeValue = "Error... retrying...";
loader.children[1].firstChild.nodeValue = "Attempt "+(attempt+1)+" of 5";
}
a = new XMLHttpRequest();
a.open("POST","/ajax/"+url,true);
a.onreadystatechange = rsc;
a.timeout = 5000;
a.ontimeout = to;
a.setRequestHeader("Content-Type","application/json");
a.send(data);
};
send();
};
The main intent behind this function is to try the request up to five times. There are cases where IE throws unusual HTTP errors and servers may fail to respond.
I've noticed that the abort()
method does not seem to stop the connection as expected. To confirm, I created a simple PHP script:
<?php
sleep(60);
touch("test/".uniqid());
die("Request completed.");
?>
With the code above, a file is generated using the current uniqid()
, helping me track when the sleep(60)
finishes.
Expected outcome:
The request gets sent
After five seconds, the message changes to "Error... Retrying... Attempt 2/5"
This continues until Attempt 5/5, leading to failure.
All the requests to the PHP file should be aborted, resulting in either five files in the "test" folder, spaced 5 seconds apart, or none, assuming ignore_user_abort is disabled.
Observed behavior (in IE9):
The request is made
The attempts display correctly as intended
After five tries, an error message appears
Then, I cannot load any pages for five minutes straight.
On the server side, there are five files spaced one minute apart
I'm puzzled by this situation because on the server end, Requests 3, 4, and 5 are being executed minutes after the "Timeout" message pops up on the browser.
If it's relevant, the page executing these AJAX calls is inside an iframe. Reloading the iframe (using
iframe.contentWindow.location.reload()
) does NOT resolve the issue—it still waits for those five requests to complete.
Why is this issue occurring and how can it be resolved?
EDIT: For further investigation, I ran the test again while monitoring network activity with Developer Tools. Here are the results:
URL Method Result Type Received Taken Initiator
/ajax/testto (Aborted) 0 B < 1 ms (Pending...)
/ajax/testto (Aborted) 0 B 125 ms (Pending...)
/ajax/testto (Aborted) 0 B 125 ms (Pending...)
/ajax/testto (Aborted) 0 B 125 ms (Pending...)
/ajax/testto (Aborted) 0 B 124 ms (Pending...)