What is the mechanism behind the functionality of the XMLHttpRequest() object?

After spending some time learning JavaScript, I recently delved into AJAX and encountered something unusual that caught my attention.

Consider this sample code snippet:


var receiveReq = XMLHttpRequest();      
//Initialize the asynchronous request.
function sayHello() {
    //Check if our XMLHttpRequest object is not in the middle of another request, then start a new asynchronous call.
    if (receiveReq.readyState == 4 || receiveReq.readyState == 0) {
        //Set up the connection for a GET call to SayHello.html. The true value explicitly sets the request as asynchronous.
        receiveReq.open("GET", 'SayHello.html', true);
        //Define the function to handle state changes in the XMLHttpRequest object.
        receiveReq.onreadystatechange = handleSayHello; 
        //Make the actual request.
        receiveReq.send(null);
    }           
}

function handleSayHello() {
    //Verify if the XmlHttpRequest's state indicates completion.
    if (receiveReq.readyState == 4) {
        //Update the content of the span element with the result of the asynchronous call.
        document.getElementById('span_result').innerHTML = receiveReq.responseText;
    }           
}

When executing this function, it seems like the browser repeatedly invokes handleSayHello(). This behavior puzzles me because I have never seen anything like this in JavaScript or any other language. How does this mechanism operate, and are there similar features in JavaScript?

Moreover, what would occur if receiveReq.readyState was neither 0 nor 4 when the if statement in sayHello() is triggered?

Edit:

I made a slight adjustment to the sayHello() function, resulting in the following update:


function sayHello() {
    //Initiate a new asynchronous call only if our XmlHttpRequest object is not already processing a request.
    if (receiveReq.readyState == 4) {
        receiveReq.open("GET", 'SayHello.html', true);
        receiveReq.onreadystatechange = handleSayHello; 
        receiveReq.send(null);
    }     
    else
        alert("readyState = " + receiveReq.readyState);      
}

To my surprise, this refined code snippet still functions properly. What struck me is that this if statement executes twice: once when readyState equals 0, and again when readyState equals 4. How did this dual execution occur?

Below is the complete source code:


<html>
    <head>
        <title>The Hello World of AJAX</title>
        <script language="JavaScript" type="text/javascript">
            function getXmlHttpRequestObject() {
                if (window.XMLHttpRequest) {
                    return new XMLHttpRequest();
                } else if(window.ActiveXObject) {
                    return new ActiveXObject("Microsoft.XMLHTTP");
                } else {
                    alert("Your browser doesn't support the XmlHttpRequest object. Please consider upgrading to Firefox.");
                }
            }           

            var receiveReq = getXmlHttpRequestObject();     

            function sayHello() {
                if (receiveReq.readyState == 4 || receiveReq.readyState == 0) {
                    receiveReq.open("GET", 'SayHello.html', true);
                    receiveReq.onreadystatechange = handleSayHello; 
                    receiveReq.send(null);
                }           
            }

            function handleSayHello() {
                if (receiveReq.readyState == 4) {
                    document.getElementById('span_result').innerHTML = receiveReq.responseText;
                }
            }
            </script>
    </head>
    <body>
        <a href="javascript:sayHello();">Say Hello</a><br />
        <span id="span_result"></span>
    </body>
</html>

The content inside SayHello.html simply says:

hello, world

Answer №1

By connecting the onreadystatechange event to your handleSayHello function in this line of code, you are setting up a situation where the handle function will be executed multiple times since onreadystatechange is triggered multiple times throughout the lifecycle of an XMLHttpRequest request.

receiveReq.onreadystatechange = handleSayHello; 

If you want more information on readystate values and changes, check out this helpful article.

Answer №2

Each time you make a request, a new XHR instance is required.
When the XHR's readyState changes, the onreadystatechange event listener will be triggered.

function sayHello() {
    var receiveReq = new XMLHttpRequest();      
    receiveReq.open("GET", 'SayHello.html', true);
    receiveReq.onreadystatechange = function  (  ) {
        if (receiveReq.readyState == 4 ) {
        //do something.
            handleSayHello ()
     }
    }; 
    receiveReq.send(null);
}
function handleSayHello (  ) {

}

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

"Upon loading an FBX file in Threejs, some model parts are not displayed

Hello, I am in need of assistance. I am currently working on importing FBX models into Threejs and here is the import code that I am using: let loader = new FBXLoader(); loader.load(model.obj_path, object => { let mix = new THREE.AnimationMixer(objec ...

Adjusting the size of an HTML5 canvas using a class function when a resize event occurs

I'm attempting to adjust the size of a canvas element using a resizeCanvas() method triggered by a resize event. When I directly call the method, the canvas resizes without any issues. However, when the event handler triggers subsequent calls, I encou ...

What sets apart local and global variables when it comes to JavaScript?

It has come to my attention that in the realm of JavaScript, there are instances where a variable is created within a function without explicitly declaring it with var. For instance: function myfunction() { x = 10; var y = 10; } What sets these ...

Verifying that objects are eligible for garbage collection

My program in node.js receives a high volume of messages. Each time a message is received, I create a new object and pass the message content to it. Inside the constructor of the new object, various operations are performed, including some mongo tasks with ...

Remove the lesser of two duplicate items from the list by comparing their count keys

Here is a challenge I encountered with a grocery list that required filtering out duplicates and only keeping the duplicate with the higher count, while also retaining non-duplicate items. I managed to achieve this through trial and error programming, bu ...

Having trouble with Next.js getStaticProps? Getting a TypeError that says "Cannot read properties of undefined (reading 'map')"?

My latest project was built using create-next-app as a base. In the Blog.js page, I attempted to fetch data from https://jsonplaceholder.typicode.com/posts by utilizing the getStaticProps() function. I followed the instructions provided in this guide: htt ...

A guide on retrieving nested objects from my API and parsing the resulting data in each iteration for individual elements

Struggling to update my website with a new API, specifically with accessing nested objects in a loop. Still trying to wrap my head around ajax and JSON concepts. Take a look at the API output and JS code I've been working on for a better understanding ...

What could be causing the issue of receiving the error message: "Uncaught TypeError: Cannot read property 'Title' of undefined"?

I am currently working on developing an AJAX web application. One of the functions I have is aimed at requesting a JSON object and then utilizing it to refresh the website content. Below is the portion of JavaScript causing an issue (Lines 8 - 16): windo ...

Exploring nested optgroup functionality in React.js

Within my code, I am utilizing a nested optgroup: <select> <optgroup label="A"> <optgroup label="B"> <option>C</option> <option>D</option> <option>G</option> </optg ...

Utilizing JSONP in the perfect combination of Jquery version 1.9 and Jersey version 2.5

I've searched extensively without finding a solution that meets my requirements. While I came across some similar threads here, here, and here, none of them resolved my issue or I failed to comprehend the solutions provided. Additionally, I have revie ...

The flask application encounters a 404 error when trying to access the favicon.ico file

Upon reviewing my logfile, I noticed numerous entries indicating attempts to load files like /favicon.ico GET - /favicon.ico GET - /apple-touch-icon.png GET - /apple-touch-icon-precomposed.png I have researched this issue extensively online, but have bee ...

Dealing with 404 Errors in AngularJS using ui-router's resolve feature

As a newcomer to AngularJS and ui-router, I am currently facing the challenge of handling 404 errors for resources not found. My goal is to display an error message without changing the URL in the address bar. Here is how I have configured my states: app ...

The installation of package.json is unsuccessful, as it will only proceed with an empty name and version

Having trouble installing the package.json file after updating to the latest version of Node on my Windows PC. When trying to run npm, an error was thrown. Any help would be greatly appreciated. Command Prompt C:\Users\Felix\Desktop\ ...

When combining React and ReactDOM with browserify, the resulting bundle size exceeds that of react.min.js and react-dom.min.js

I'm currently working through the React beginner's tutorial and things are going smoothly so far. However, I decided to delve into importing external packages and began using tools like npm, browserify, watchify, etc. In the tutorial, there is a ...

Learn how to show image information in a separate div by clicking on the image using jQuery

Is there a way to show or hide information of an image in a separate div by clicking on the image itself? $(document).ready(function () { $(".cell").click(function () { $(this).find("span").toggle("slow"); }) }); <div class="cell"> ...

Unable to access a specific URL for the chosen items

I am looking to navigate to specific links when clicking on particular planets using raycaster. However, the current issue is that I get redirected to the URL of the last planet (referred to as category) whenever I click anywhere on the canvas. I have sepa ...

Different techniques to access values in a JSON array without relying on specific index positions

After making a request to an API, I received a JSON array with various attributes. One of the attributes is "State" and my task is to extract all the "EventName"(s) where State: "PR". The user will select the state from a dropdown menu. In order to achiev ...

Disable the default page scrolling behavior when collapsing an accordion section in Bootstrap 4 framework

Incorporating a Bootstrap 4 accordion with an expanded body section that causes the content below to scroll up when collapsed. To address this issue, attempting to scroll to the top of the clicked header and prevent undesirable scrolling from the collapse ...

Adjust the Appearance of Highcharts Legend Post-Rendering

After a Highchart is rendered, is it possible to modify the display settings without redrawing the chart? For instance, I would like to relocate the legend box from the right to the bottom upon screen resize, as illustrated in this image: --Example Pictur ...

Is it possible to conduct an auction in JavaScript without using the settimeout or setinterval functions?

I'm currently working on creating an auction site and I need help improving its speed and performance. I've been using setInterval and setTimeout functions for the countdown, but it's quite slow as a request is sent to the server every secon ...