Is the xmlhttprequest timeout/abort feature not functioning as anticipated?

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...)

Answer №1

It appears that a limitation exists with the timeout and ontimeout not being fully implemented in certain scenarios:

var hasTimeout = 'timeout' in new XMLHttpRequest(); // returns false

This issue is evident in Chrome 16 and Firefox 7 where the expected result should be true based on the specified criteria:

The timeout attribute should return its assigned value, initially set to zero.

While these features have been outlined in the XHR 2 specification since September 7, 2010, they are still categorized under the "Working Draft" phase as indicated by the document released on February 25, 2008. Hence, the alignment of implementations with this spec may vary.


In cases where these functionalities are unavailable, an alternative approach could involve leveraging onabort and setTimeout (as highlighted in your comment):

// snip

to = function() {
    attempt++;
    if( attempt < 5)
        send();
    else if( !silent) {
        console.log("Request Timeout\nFailed to access "+url);
    }
};

// snip

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;
    setTimeout(function () {     /* vs. a.timeout */
        if (a.readyState < 4) {
            a.abort();
        }
    }, 5000);
    a.onabort = to;              /* vs. a.ontimeout */
    a.setRequestHeader("Content-Type","application/json");
    a.send(data);
    console.log('HTTP Requesting: %s', url);
};

// snip

For demonstration, refer to this example link -- The ?delay=2 scenario should complete successfully, while the ?delay=10 situation reaches the retry limit after 5 attempts.

Answer №2

After executing your code, I encountered the error c00c023f. Upon further investigation, I stumbled upon a potential solution:

It seems like this issue bears resemblance to what you're currently facing.

Furthermore, there is a related inquiry on Stack Overflow that addresses the same issue and provides a resolution (referenced from the aforementioned link): IE 9 Javascript error c00c023f

Answer №3

To prevent the request from being aborted prematurely, consider implementing the following steps:

request.onreadystatechange = function() {};

Additionally, ensure to include a conditional check before calling the abort function:

if( request.readyState > 0 && request.readyState < 4 ) {
    request.abort();
}

Answer №4

Encountered a similar issue which was traced back to a problem with PHP session handling. When a session is active, all subsequent requests from the same session are forced to wait.

<?php
    session_write_close();
    sleep(60);
    touch("test/".uniqid());
    die("Request completed.");
?>

This solution wouldn't be of any use if you haven't initiated the session in the first place :)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discover the Power of Node.js with the @aws-sdk/client-s3 Package, Leveraging AWS CLI Credentials Stored in

A Nodejs project has been set up with media files stored in an S3 Bucket and utilizing the @aws-sdk/client-s3 as the AWS SDK Client. The project consists of two important files, namely .env and S3Bucket.js. The content of .env (located in the root directo ...

Ensure that autocorrect is set to suggest the nearest possible quantity form in WordPress

I'm currently in the process of creating a webshop using WooCommerce. Our quantity system is a bit unique, as we are using WooCommerce advanced quantity, which means that quantities increase by 0.72 increments (e.g. 0.72, 1.44, 2.16 etc). The +/- butt ...

Utilizing class attributes within multiple classes

I have created a custom class called MutationValidator as follows: const ERR_MSG = 'Error1'; @Service() export class MutationValidator { .. } This class is used in another class like so: import { MutationValidator } from './mutation ...

The steps to triggering a button click after e.preventDefault()

When attempting to prevent a click() event of a button by using preventDefault() after unbinding the button with unbind(), I encountered an issue where it did not work as expected. <script> $("#update2FAButton").on("click",function(e){ e.pre ...

Encountering a problem in a NextJS application where an error occurs stating "cannot read property of undefined (reading setState)" within

In an attempt to resolve the issue, I have linked the method to this inside the constructor. Additionally, I have utilized the arrow function technique to address the problem at hand. Despite these efforts, I continue to encounter the following error: Unha ...

Unable to establish a connection with Metamask

Looking to connect to Metamask and retrieve the account balance: <!DOCTYPE html> <html> <head> <title>Testing Ethereum with Metamask</title> <meta charset="UTF-8"> <meta name=&quo ...

The ajax code is failing to retrieve the data from the table and populate it in the

hi guys i have an issue on ajax. where ajax can't work to take the data of second rows. This's code in model function getdtbarang($barcode = FALSE) { if ($barcode === FALSE) { $query = $this->db1->get(&a ...

Activate dark mode automatically in material-ui

According to the official documentation: The documentation mentions that a dark mode theme will be automatically generated and reflected in the UI, but I am encountering issues with it. Dependencies: "@emotion/styled": "^11.0.0", ...

Searching to loop through JSON within a Sequelize / Postgres database query in order to identify a corresponding value

Hello everyone, I'm new here so please bear with me. I'm currently working on a project using Sequelize with PostgresDB in Node and I need to search for a contact by email using findOrCreate function. The email entry is stored in JSON format (se ...

Using the Angular translate filter within a ternary operator

I am currently working on translating my project into a different language. To do this, I have implemented the Angular Translate library and uploaded an external JSON file containing all the translations. Here is an example of how it looks: { "hello_wor ...

Enhancing PHP function speed through pre-compilation with Ajax

I am curious about compiling server side functions in PHP with Ajax, specifically when multiple asynchronous calls are made to the same server side script. Let's consider a PHP script called "msg.php": <?php function msg(){ $list1 = "hello world ...

Having trouble with the position function in JavaScript?

I'm working on creating a small game, but I've encountered some difficulties at the start. Every time I attempt to obtain the position of track or trackCont, it consistently returns x: 0, y: 0. The DIV doesn't move to the correct position w ...

The parameter '{ validator: any; }' cannot be assigned to the ValidatorFn type in this context

I am currently experiencing a challenge while attempting to create a custom validator using Angular. I have created a form for my sign-up page and wanted to ensure that the password and confirm password fields match by implementing a custom validator. Des ...

Issue with displaying PDF files on Google Chrome due to a software glitch

Recently, I encountered a puzzling issue on Google Chrome. I am not sure if the error lies with Google or within my code. When I set the div as display: none; and then show it again, the PDF view only shows a grey background. However, if I zoom in or out, ...

Make sure to refresh the model using an Ajax request in Spring MVC

I have a page where I use AJAX to insert data into my database. On that same page, I display a table of records that are inserted. Each time I add a new record, I want to update the content of the table. Here is what I have implemented: @RequestMapping(va ...

Issue with AngularJS ng-model not updating the value of a hidden input

My goal is to transmit form data using hidden input like this: <input type="hidden" required ng-model="formHolder.template[position].itemKey[itr]" ng-value="[[ formItem ]]" /> The value of formItem can be any string. Issues arise when the strings c ...

Firefox Issue: SetTimeout Redirect Function Not Functioning Properly

Working on a page that redirects users to an installed application or a webpage as a fallback. This is implemented using ClientScript.RegisterStartupScript when the page loads, with a Javascript snippet like this: <script type='text/javascript&apo ...

Issue - The 'defaultValue' is failing to load the state value, and the 'value' is not being updated when changed

My current setup involves an input field in my MovieInput.tsx file: <input id="inputMovieTitle" type="text" onChange={ e => titleHandleChange(e) } value={ getTitle() }> </input> This is how the titleHandleChange function ...

Pseudo-element fails to display in React when applied to a paragraph tag, even with display block property set

I am experiencing an issue where the pseudo element ::after is not appearing in my browser. I am currently working with React.js and Material UI's makeStyles. Here is the code snippet causing the problem: modalTitle: { borderBottom: '2px sol ...

When I use .fadeToggle, my div transitions smoothly between visible and hidden states

Looking to create a sleek navigation menu that showcases a colored square when hovered over? I'm currently experiencing an issue where the squares are not aligning correctly with the items being hovered. Switching the position to absolute would likely ...