How do you make synchronous HTTP request in JavaScript?


In the current digital terrain, the act of making HTTP requests is a vital component in transmitting and receiving data between the client and server. Asynchronous requests have gained prevalence as they provide a non-blocking experience, which ultimately enhances the overall user experience. Nevertheless, there are certain situations where synchronous HTTP requests may prove necessary or preferable. In the ensuing narrative, we shall delve into the algorithm for creating synchronous HTTP requests using JavaScript. We will also explore two distinct approaches with their corresponding code explanations and practical applications.

Algorithm

To initiate synchronous HTTP requests in JavaScript, one must execute a basic algorithm that comprises of the subsequent phases −

  • Firstly, spawn an example of the HTTP request object.

  • Secondly, adjust the request by stipulating the methodology, uniform resource locator (URL), and enabling the request to synchronize mode.

  • Thirdly, dispatch the request.

  • Fourthly, await the response.

  • Lastly, handle the response accordingly.

Approaches

Using XMLHttpRequest

The XMLHttpRequest is a pre-existing object in JavaScript that has been in use for a considerable duration. Despite its substitution by contemporary alternatives, it still functions adeptly for executing synchronous HTTP requests. Below is an illustration of how to implement XMLHttpRequest −

function synchronousRequest(url) {
   const xhr = new XMLHttpRequest();
   xhr.open('GET', url, false);
   xhr.send(null);
   if (xhr.status === 200) {
      return xhr.responseText;
   } else {
      throw new Error('Request failed: ' + xhr.statusText);
   }
}

In this example, we first create a new XMLHttpRequest instance. Next, we call the open() method to configure the request. The first argument is the HTTP method (GET), the second argument is the URL, and the third argument is a boolean indicating whether the request should be asynchronous (false for synchronous requests). Finally, we send the request using the send() method and wait for the response. If the status is 200 (OK), we return the response text; otherwise, we throw an error.

Example

Using the synchronousRequest function defined earlier −

try {
   const url = 'https://api.example.com/data';
   const responseData = synchronousRequest(url);
   console.log('Response data:', responseData);
} catch (error) {
   console.error('Error:', error.message);
}

In this illustration, we invoke the synchronousRequest function with a prototype URL. If the request prospers, we log the response information to the console. However, if it fails, we log the error message to the console.

Using Fetch API

The Fetch API is a modern alternative to XMLHttpRequest and is designed to be more flexible and easier to use. Unfortunately, the native fetch() function does not support synchronous requests. However, you can use async/await to create a synchronous-like behavior −

async function synchronousFetch(url) {
   const response = await fetch(url);
   if (response.ok) {
      const data = await response.text();
      return data;
   } else {
      throw new Error('Request failed: ' + response.statusText);
   }
}

In this instance, we utilize the fetch() function that furnishes a Promise. We apply the await keyword to pause the execution until the Promise concludes before continuing to the subsequent line of code. If the response is satisfactory, we retrieve the response text; otherwise, we trigger an error.

Example

Using the synchronousFetch function defined earlier −

import React, { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
   const [responseData, setResponseData] = useState(null);
   useEffect(() => {
      (async () => {
         try {
            const url = "https://jsonplaceholder.typicode.com/todos/1";
            const response = await fetch(url);
            if (!response.ok) {
               throw new Error(`HTTP error! Status: ${response.status}`);
            }
            const data = await response.json();
            setResponseData(data);
         } catch (error) {
            console.error("Error:", error.message);
         }
      })();
   }, []);
   return (
      <div className="App">
         <h1>API Data</h1>
         {responseData ? (
            <pre>{JSON.stringify(responseData, null, 2)}</pre>
         ) : (
            <p>Loading...</p>
         )}
      </div>
   );
}

Output

API Data
{
   "userId": 1,
   "id": 1,
   "title": "delectus aut autem",
   "completed": false
}

In this example, we call the synchronousFetch function within an async function to properly handle the await keyword. Like the previous example, we log the response data to the console if the request is successful, and log the error message otherwise.

Conclusion

While asynchronous requests are generally preferred for their non-blocking nature, synchronous HTTP requests in JavaScript still have their use cases. We've discussed the algorithm for making synchronous HTTP requests and explored two different approaches, including the older XMLHttpRequest method and the more modern Fetch API with async/await. Remember that synchronous requests should be used cautiously, as they can block the execution of your JavaScript code and negatively impact the user experience.

Updated on: 17-Apr-2023

5K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements