Tutorials Logic, IN info@tutorialslogic.com

What Is AJAX? How It Works, Why It Matters

The Problem AJAX Solved

Before AJAX existed, every interaction that needed server data caused a full page reload. Click a button, wait for the whole page to reload, see the result. AJAX broke that pattern by letting JavaScript send requests to the server in the background and update only the part of the page that changed.

The name stands for Asynchronous JavaScript and XML, but almost nobody uses XML anymore. Today it means any technique where JavaScript fetches data from a server without navigating away from the current page. The modern tool for this is the Fetch API.

AJAX is not a library or a framework. It is a browser capability. Every modern browser can send HTTP requests from JavaScript. React, Vue, Angular, and every frontend framework ultimately relies on it to talk to APIs.

In the early web, every form submission or data request meant the browser sent a request to the server, the server responded with a complete HTML page, and the browser rendered the whole thing from scratch. If you were filling out a form and wanted to check if a username was available, you had to submit the form, wait for the page to reload, and see the validation result.

Google Maps in 2005 demonstrated something different — you could drag the map and new tiles would load smoothly without any page reload. Gmail showed that emails could appear without the page refreshing. These used a browser feature called XMLHttpRequest that had been available since 1999 but was not widely used.

Jesse James Garrett named this pattern "AJAX" in 2005. The core idea: JavaScript can send an HTTP request, wait for the response in the background, and update only the part of the page that needs changing. Everything else stays intact.

How AJAX Actually Works

When JavaScript makes an AJAX request, it creates an HTTP request object (XMLHttpRequest or fetch), sends it to a URL, and provides a callback or Promise to handle the response. The browser sends the request in the background while the main thread keeps running.

The response can be anything the server sends — JSON, HTML fragments, plain text, binary data. In modern applications it is almost always JSON, which JavaScript can parse directly into objects and arrays.

  • User triggers an action (click, type, scroll, page load)
  • JavaScript calls fetch() or creates an XMLHttpRequest
  • Browser sends the HTTP request to the server in the background
  • Server processes the request and returns data (usually JSON)
  • JavaScript receives the response and updates the relevant DOM element
  • User sees updated content — no page reload, no lost scroll position

Fetch API — The Modern Way

Fetch API — The Modern Way
// Fetch user data and display it without reloading the page
async function loadUserProfile(userId) {
  const response = await fetch(`/api/users/${userId}`);

  if (!response.ok) {
    // Always check this — fetch() only rejects on network failure,
    // not on HTTP errors like 404 or 500
    throw new Error(`Server returned ${response.status}`);
  }

  const user = await response.json();

  // Update only the profile section — rest of page unchanged
  document.getElementById('user-name').textContent = user.name;
  document.getElementById('user-email').textContent = user.email;
}

loadUserProfile(42).catch(err => {
  document.getElementById('error-msg').textContent = 'Could not load profile.';
});

XMLHttpRequest — The Original Way (Still in Legacy Code)

XMLHttpRequest — The Original Way (Still in Legacy Code)
// You will see this in older codebases — use fetch() for new code
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/users/42');

xhr.onload = function () {
  if (xhr.status === 200) {
    const user = JSON.parse(xhr.responseText);
    document.getElementById('user-name').textContent = user.name;
  } else {
    console.error('Request failed:', xhr.status);
  }
};

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

xhr.send();

Traditional Page vs AJAX — The Real Difference

In a traditional web app, clicking "Add to Cart" sends a POST request, the server processes it, and the server sends back a complete HTML page. Your scroll position resets, the browser re-renders everything, and any unsaved form input is lost.

With AJAX, clicking "Add to Cart" sends a POST request in the background. The server responds with a small JSON object like {"cartCount": 3}. JavaScript updates just the cart icon number. You stay where you are on the page.

Scenario Traditional (Full Reload) AJAX (Partial Update)
Add item to cart Full page reload, scroll resets Cart count updates, stay on page
Check username availability Submit form, wait for reload Instant feedback as you type
Load more posts Navigate to page 2 Posts append below existing ones
Search autocomplete Not possible without reload Suggestions appear instantly
Like / upvote Page reload to confirm Count updates instantly

Sending Data — POST Requests with AJAX

GET requests retrieve data. POST requests send data. AJAX works with both. Here is a typical pattern for submitting a form without reloading the page:

Submit a Form with AJAX (POST)

Submit a Form with AJAX (POST)
async function submitContactForm(event) {
  event.preventDefault(); // Stop the default form reload

  const form = event.target;
  const data = {
    name: form.name.value,
    email: form.email.value,
    message: form.message.value,
  };

  try {
    const response = await fetch('/api/contact', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),  // Must stringify — cannot send plain object
    });

    if (!response.ok) throw new Error('Submission failed');

    const result = await response.json();
    document.getElementById('form-status').textContent = result.message;
    form.reset();
  } catch (err) {
    document.getElementById('form-status').textContent = 'Something went wrong. Please try again.';
  }
}

document.getElementById('contact-form').addEventListener('submit', submitContactForm);

CORS — The Most Common AJAX Problem

When your JavaScript on example.com tries to fetch data from api.otherdomain.com, the browser blocks it by default. This is the Same-Origin Policy — a security rule that prevents malicious sites from making requests on behalf of users.

The server at api.otherdomain.com must explicitly allow cross-origin requests using CORS headers. If it does not, the browser blocks the response. The fix is server-side — the API must send the correct Access-Control-Allow-Origin header.

During development, if you run a frontend on localhost:3000 and an API on localhost:8080, that is still a cross-origin request and requires CORS configuration. This catches almost every beginner who sets up a separate frontend and backend.

  • CORS errors appear in the browser console: "Access to fetch at X from origin Y has been blocked"
  • The fix is always server-side — add the correct CORS headers to your API responses
  • Never use browser extensions to bypass CORS in development — it hides real problems
  • Your own APIs need: Access-Control-Allow-Origin: * (or a specific domain)

Fetch API vs XMLHttpRequest — Which to Use

Use the Fetch API for all new code. It returns Promises, works cleanly with async/await, and has a much more readable API. XMLHttpRequest is callback-based and verbose.

One gotcha with fetch: it does not reject on HTTP errors. A 404 or 500 response resolves the Promise normally. You must check response.ok yourself. This trips up almost everyone coming from jQuery or Axios which throw on non-2xx responses.

  • fetch() — use for all new projects. Returns a Promise. Works with async/await.
  • XMLHttpRequest — legacy API. Still works everywhere. Avoid in new code.
  • Axios — popular third-party library. Throws on HTTP errors automatically. Good for larger apps.
  • jQuery $.ajax() — old library method. You may see this in legacy projects.

Common Beginner Misunderstandings

These are the things that consistently confuse developers learning AJAX for the first time.

  • fetch() does not throw on 404 or 500 — you must check response.ok manually. This is the most common fetch() bug.
  • AJAX is not a library — it is a browser capability. You do not install AJAX.
  • Async does not mean instant — the request still takes network time. Always show a loading state.
  • CORS errors are server-side problems, not frontend code bugs. You cannot fix them in JavaScript.
  • JSON.stringify() is required when sending objects in POST body — you cannot send a plain object.
  • The response body can only be read once — calling response.json() a second time throws an error.

Interview Important Points

These are the AJAX questions that come up most often in frontend developer interviews.

  • What is AJAX? — A technique for sending HTTP requests from JavaScript without reloading the page.
  • Difference between fetch() and XMLHttpRequest? — fetch() is Promise-based and cleaner. XHR is callback-based and older.
  • Why does fetch() not throw on 404? — fetch() only rejects on network failure. Check response.ok for HTTP errors.
  • What is CORS? — A browser security mechanism blocking cross-origin requests unless the server explicitly allows them.
  • How do you handle fetch() errors? — Check response.ok for HTTP errors. Use try/catch around await for network errors.
Before you move on

Mastery Check

6 checks
  • Explain what problem AJAX solves without using technical jargon.
  • Write a fetch() call that loads JSON data and updates a DOM element.
  • Check response.ok before processing the response — never assume success.
  • Handle the error case — show a user-friendly message when the request fails.
  • Explain why CORS happens and what needs to change to fix it.
  • Send a POST request with a JSON body using fetch().

Troubleshooting Boundary

Try this next

AJAX First Steps

0 of 5 completed

AJAX Questions Learners Ask

Yes. React, Vue, and Angular all use fetch() or axios under the hood to talk to APIs. Understanding AJAX means understanding what these frameworks are doing for you. When something breaks, you need to know what is happening at the HTTP level.

Almost certainly a CORS issue. Postman does not enforce the Same-Origin Policy. The browser blocks the response because the server did not include the Access-Control-Allow-Origin header. Fix it server-side.

fetch() works without any dependencies. Axios adds automatic JSON parsing, throws on HTTP errors by default, and has interceptors for auth tokens. For simple use cases, fetch() is fine. For larger apps, Axios saves boilerplate.

Next Step
Next Practice

Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.