← Back to JavaScript Course | Chapter 9: Async & Web APIs | Lesson 11 of 26

JS AJAX Intro

Understanding AJAX begins with the request/response cycle it automates: JavaScript initiates a request, the browser sends it to a server in the background, and once a response arrives, a callback (or resolved promise) processes it -- all without the user experiencing any full-page reload or interruption.

The Request/Response Cycle

An AJAX interaction has three stages: your JavaScript code initiates a request (specifying a URL and optional data), the browser sends it to the server and waits in the background, and once a response arrives, your registered callback or promise handler processes it.

Note: Sketch out the three stages -- initiate, wait, handle -- before writing AJAX code, to keep the asynchronous flow clear in your mind.
Warning: Code written directly after an AJAX call, expecting the response to already be available, will run before the response has actually arrived -- this is the single most common AJAX mistake for beginners.

उदाहरण: The Request/Response Cycle

javascript
// Define the method `fetch` taking `"data.php"`
// Define the method `fetch` taking `"data.php"`
fetch("data.php")
  // On success, run this with the resolved value as `response`
  // On success, run this with the resolved value as `response`
  .then(response => response.json())
  // On success, run this with the resolved value as `data`
  // On success, run this with the resolved value as `data`
  .then(data => console.log("Response handled:", data));

Why AJAX Requests Are Asynchronous

A network request to a server can take anywhere from milliseconds to several seconds, depending on the server and connection -- if JavaScript waited (blocked) for every request to finish before continuing, the entire page would freeze and become unresponsive during that wait, which is exactly what asynchronous requests avoid.

Note: Embrace the asynchronous nature of AJAX rather than fighting it -- structure your code around callbacks, promises, or async/await instead of trying to force synchronous-style waiting.
Warning: A synchronous version of XMLHttpRequest technically exists but is deprecated and freezes the entire page during the request -- it should never be used in modern code.

उदाहरण: Why AJAX Requests Are Asynchronous

javascript
console.log("Request started");
fetch("data.php").then(r => r.json()).then(data => console.log("Response arrived:", data));
console.log("Page stays responsive while waiting"); // logs before the fetch resolves

Same-Origin Policy and CORS

By default, a browser blocks JavaScript from making an AJAX request to a different origin (domain, protocol, or port) than the page itself, as a security measure -- a server can explicitly opt in to allow cross-origin requests by sending CORS (Cross-Origin Resource Sharing) response headers.

Note: When an AJAX request to a different domain fails with a CORS-related console error, that server needs to add the appropriate Access-Control-Allow-Origin header -- it is not something fixable purely from the client side.
Warning: A CORS error appears in the browser console but is not catchable in JavaScript the same way as a normal network error, since the browser blocks the response before your code ever sees it.

उदाहरण: Same-Origin Policy and CORS

javascript
fetch("data.php").then(r => r.json()).then(data => console.log(data));
// Cross-origin requests need the server to send CORS headers to be allowed

Handling Success and Failure

A well-built AJAX interaction plans for both outcomes: a successful response that updates the page, and a failed request (network error, timeout, or server error) that shows the user a clear message instead of leaving them staring at a stuck loading state.

Note: Always pair a .then() success handler with a .catch() (or a try/catch around await) failure handler, so a failed request has somewhere defined to go.
Warning: An AJAX request that fails silently, with no visible feedback and no console error handling, leaves users confused about whether anything happened at all.

उदाहरण: Handling Success and Failure

javascript
// Define the method `fetch` taking `"data.php"`
// Define the method `fetch` taking `"data.php"`
fetch("data.php")
  // On success, run this with the resolved value as `response`
  // On success, run this with the resolved value as `response`
  .then(response => {
    if (!response.ok) throw new Error("Request failed");
    // Return `response.json()` from this function
    // Return `response.json()` from this function
    return response.json();
  })
  // On success, run this with the resolved value as `data`
  // On success, run this with the resolved value as `data`
  .then(data => console.log("Success:", data))
  // On failure, run this with the error as `error`
  // On failure, run this with the error as `error`
  .catch(error => console.log("Show user a message:", error.message));

A Complete Beginner AJAX Example

Combining everything from this introduction: a button click initiates a request, the page shows a loading state while waiting, and the response (success or failure) updates the page -- the complete, minimal shape every AJAX interaction follows, regardless of how complex the actual application logic becomes.

Note: Use this same basic shape -- trigger, loading state, success/failure handling -- as the mental template for any new AJAX interaction you build.
Warning: Skipping the loading-state feedback on a request that might take a noticeable moment can make an application feel unresponsive or broken, even though it is actually working correctly.

उदाहरण: A Complete Beginner AJAX Example

javascript
<button id="loadBtn">Load Data</button>
<p id="status">Idle</p>
<script>
  document.getElementById("loadBtn").addEventListener("click", () => {
    document.getElementById("status").textContent = "Loading...";
    // Define the method `fetch` taking `"data.php"`
    fetch("data.php")
      // On success, run this with the resolved value as `r`
      .then(r => r.json())
      // On success, run this with the resolved value as `data`
      .then(data => document.getElementById("status").textContent = "Loaded: " + data.message)
      .catch(() => document.getElementById("status").textContent = "Failed");
  });
</script>
Live Example
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.