Note that there are some explanatory texts on larger screens.

plurals
  1. POxmlhttprequest timeout / abort not working as expected?
    primarykey
    data
    text
    <p>Here is my AJAX function:</p> <pre><code>/** * Send an AJAX request * * @param url The URL to call (located in the /ajax/ directory) * @param data The data to send (will be serialised with JSON) * @param callback The function to call with the response text * @param silent If true, doesn't show errors to the user * @param loader The element containing "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 &gt; 999) { // IE sometimes throws 12152 attempt++; if( attempt &lt; 5) send(); else if( !silent) { alert("HTTP Error "+a.status+" "+a.statusText+"&lt;br /&gt;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 &lt; 5) send(); else if( !silent) { alert("Request Timeout\nFailed to access "+url); } }; data = JSON.stringify(data); var send = function() { if( loader &amp;&amp; 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(); }; </code></pre> <p>The general idea is to attempt the request up to five times. Sometimes IE fails with an unusual HTTP error (12xxx), and sometimes the server may fail to respond.</p> <p>The problem I'm having is that the <code>abort()</code> call doesn't appear to be aborting the connection. To test, I made a simple PHP script:</p> <pre><code>&lt;?php sleep(60); touch("test/".uniqid()); die("Request completed."); ?&gt; </code></pre> <p>The <code>touch()</code> call creates a file with the current <code>uniqid()</code> - by looking at the modification time I can see the time the <code>sleep(60)</code> ended.</p> <p>Expected behaviour:</p> <blockquote> <p>The request is sent<br> After five seconds, the text changes to "Error... Retying... Attempt 2/5"<br> Repeat the above up until Attempt 5/5, then fail.<br> The five calls to the PHP file are aborted, and either there will be five files in the "test" folder, spaced 5 seconds apart, or there will be none because ignore_user_abort is off.</p> </blockquote> <p>Observed behaviour (in IE9):</p> <blockquote> <p>The request is sent<br> The attempt text appears and changes as it should<br> After five attempts, the error message is displayed<br> I am unable to load any pages for five whole minutes.<br> On the server, there are five files spaced one minute apart</p> </blockquote> <p>I don't know what to make of this, because on the server side Requests 3, 4 and 5 are being sent minutes after the "Timeout" error message is shown on the browser.</p> <p>If it makes any difference, the page making the AJAX calls is in an iframe. Reloading the iframe (using <code>iframe.contentWindow.location.reload()</code> does NOT fix the issue, it still waits for those five requests to go through.</p> <p>Why is this happening? How can I fix it?</p> <p><strong>EDIT:</strong> I've run the test again using Developer Tools to monitor network activity. The result is:</p> <pre><code>URL Method Result Type Received Taken Initiator /ajax/testto (Aborted) 0 B &lt; 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...) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload