JSON with AJAX and XMLHttpRequest

What is AJAX?

AJAX stands for Asynchronous JavaScript and XML. Despite the name including "XML," AJAX is most commonly used with JSON today. AJAX is a technique that allows a web page to load or send data in the background without refreshing the entire page.

Before AJAX, every time new data was needed, the whole page had to reload. AJAX changed this — now only the data is fetched, and the page updates only the part that changed. This creates a much smoother user experience, like how Gmail loads new emails or how a search box shows suggestions while typing.

The original built-in method for making AJAX requests is XMLHttpRequest (often shortened to XHR). While the modern Fetch API is now preferred, understanding XHR is important because it is still widely used in older codebases and projects.

How XMLHttpRequest Works — Step by Step

  1. Create a new XMLHttpRequest object
  2. Define what happens when the response arrives (the callback)
  3. Open a connection — specify the HTTP method (GET or POST) and the URL
  4. Send the request
  5. Receive the response and parse the JSON

Basic GET Request — Fetching JSON Data

const xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    const data = JSON.parse(xhr.responseText);
    console.log(data.name);
    console.log(data.email);
  }
};

xhr.open("GET", "https://jsonplaceholder.typicode.com/users/1", true);
xhr.send();

Let's understand what each part does:

  • new XMLHttpRequest() — creates the request object
  • onreadystatechange — a function that runs every time the request state changes
  • readyState === 4 — means the request is complete
  • status === 200 — means the server responded with success
  • xhr.responseText — the raw JSON string returned by the server
  • JSON.parse() — converts the string into a usable JavaScript object

Understanding readyState Values

ValueState NameMeaning
0UNSENTRequest has not been opened yet
1OPENEDThe open() method has been called
2HEADERS_RECEIVEDRequest has been sent; headers received
3LOADINGResponse body is being received
4DONERequest is complete — response is ready

Using the onload Event (Cleaner Approach)

Instead of checking readyState, the onload event fires only when the request is fully complete — making the code simpler:

const xhr = new XMLHttpRequest();

xhr.onload = function() {
  if (xhr.status === 200) {
    const user = JSON.parse(xhr.responseText);
    console.log("Name: " + user.name);
    console.log("City: " + user.address.city);
  } else {
    console.log("Request failed. Status: " + xhr.status);
  }
};

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

xhr.open("GET", "https://jsonplaceholder.typicode.com/users/2", true);
xhr.send();

Fetching a List (Array) of JSON Records

const xhr = new XMLHttpRequest();

xhr.onload = function() {
  if (xhr.status === 200) {
    const posts = JSON.parse(xhr.responseText);

    console.log("Total posts: " + posts.length);

    posts.slice(0, 3).forEach(function(post) {
      console.log(post.title);
    });
  }
};

xhr.open("GET", "https://jsonplaceholder.typicode.com/posts", true);
xhr.send();

Displaying XHR Response in HTML

<div id="result"></div>

<script>
const xhr = new XMLHttpRequest();

xhr.onload = function() {
  if (xhr.status === 200) {
    const user = JSON.parse(xhr.responseText);
    const container = document.getElementById("result");
    container.innerHTML =
      "<h3>" + user.name + "</h3>" +
      "<p>Email: " + user.email + "</p>" +
      "<p>Phone: " + user.phone + "</p>";
  }
};

xhr.open("GET", "https://jsonplaceholder.typicode.com/users/4", true);
xhr.send();
</script>

POST Request — Sending JSON Data to a Server

To send JSON data (like form submissions) to a server using XHR:

const xhr = new XMLHttpRequest();

const payload = {
  title: "Study Plan",
  body: "Complete all JSON topics this week.",
  userId: 7
};

xhr.onload = function() {
  if (xhr.status === 201) {
    const response = JSON.parse(xhr.responseText);
    console.log("Created post with ID: " + response.id);
  }
};

xhr.open("POST", "https://jsonplaceholder.typicode.com/posts", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(payload));

Key steps for a POST request:

  • Use xhr.open("POST", url, true)
  • Set the Content-Type header to application/json
  • Convert the object to a string using JSON.stringify() before sending
  • A status of 201 means the resource was successfully created

XHR vs Fetch API — Quick Comparison

FeatureXMLHttpRequest (XHR)Fetch API
IntroducedEarly 2000s (legacy)2015 (modern)
Code StyleCallback-based (nested)Promise-based (chainable)
ReadabilityMore verboseCleaner and simpler
async/await SupportNot directlyYes, natively
Browser SupportAll browsers including older IEAll modern browsers
When to UseLegacy code, older projectsNew projects (preferred)

Key Points to Remember

  • AJAX allows data to be loaded in the background without refreshing the page
  • XMLHttpRequest is the original AJAX tool — still found in legacy codebases
  • Always check readyState === 4 and status === 200 before reading the response
  • xhr.responseText returns the raw JSON string — always parse it with JSON.parse()
  • For POST requests, set the Content-Type header and stringify the data before sending
  • For new projects, the Fetch API is the modern and recommended alternative

Summary

XMLHttpRequest was the original way to make background HTTP requests in JavaScript and is still encountered frequently in existing web applications. Understanding XHR alongside the Fetch API gives a complete picture of how web pages communicate with servers using JSON. The core workflow remains the same in both approaches — send a request, receive a JSON string response, parse it, and use the data.

Leave a Comment

Your email address will not be published. Required fields are marked *