HVRDHVRD
JavaScript

AJAX

Detailed guide to understanding and using AJAX for making asynchronous HTTP requests in JavaScript.

AJAX stands for Asynchronous JavaScript and XML. It allows web applications to send and receive data from a server asynchronously, without requiring a full page reload. Although originally designed to work with XML, modern usage almost exclusively favors JSON.


Why Use AJAX?

  • Improves user experience by updating parts of a web page without reloading.
  • Enables fast, seamless interactions with the server.
  • Allows data fetching, form submissions, and dynamic content updates.

Traditional AJAX Using XMLHttpRequest

Basic Example

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) { // Request complete
    if (xhr.status === 200) {
      console.log('Response:', JSON.parse(xhr.responseText));
    } else {
      console.error('Error:', xhr.status);
    }
  }
};

xhr.send();

Explanation of Key Properties

  • xhr.open(method, url, async): Initializes the request.
  • xhr.onreadystatechange: Event handler called when request state changes.
  • xhr.readyState: Status of the request (4 means done).
  • xhr.status: HTTP status code.
  • xhr.responseText: Raw response as a string.

Sending Data with POST

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/submit', true);
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      console.log('Server response:', JSON.parse(xhr.responseText));
    } else {
      console.error('Error:', xhr.status);
    }
  }
};

const data = JSON.stringify({ name: 'Alice', age: 25 });
xhr.send(data);

Key Points

  • Set Content-Type header to application/json.
  • Use JSON.stringify() to serialize data.

Modern Approach: Using Fetch API Instead

While XMLHttpRequest works, the modern approach is to use the Fetch API for cleaner syntax and better promise support.

fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('Fetch error:', error));

However, understanding XMLHttpRequest is useful for legacy support and detailed control over the request lifecycle.


Handling Timeouts

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.timeout = 5000; // 5 seconds

xhr.ontimeout = function() {
  console.error('The request timed out.');
};

xhr.onload = function() {
  if (xhr.status === 200) {
    console.log('Data:', JSON.parse(xhr.responseText));
  } else {
    console.error('Error:', xhr.status);
  }
};

xhr.send();

Handling Errors

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);

xhr.onerror = function() {
  console.error('Network error occurred.');
};

xhr.onload = function() {
  if (xhr.status === 200) {
    console.log('Data:', JSON.parse(xhr.responseText));
  } else {
    console.error('Server returned error:', xhr.status);
  }
};

xhr.send();

Aborting a Request

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);

xhr.send();

// Abort the request after 2 seconds
setTimeout(() => {
  xhr.abort();
  console.log('Request aborted.');
}, 2000);

xhr.onabort = function() {
  console.log('Abort event triggered.');
};

AJAX vs Fetch API

FeatureAJAX (XMLHttpRequest)Fetch API
SyntaxVerboseCleaner with Promises
Streaming SupportNoYes
Timeout SupportYesNo (custom AbortController needed)
Older Browser SupportWidely supportedRequires polyfill in older browsers
InterceptorsManual setupRequires external libraries

Best Practices

  • Prefer JSON over XML for data exchange.
  • Always handle network errors and timeouts explicitly.
  • Use Fetch API for new projects unless legacy support is needed.
  • Avoid blocking synchronous requests.
  • Sanitize inputs to prevent injection attacks.