iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

AJAX XMLHttp

XMLHttpRequest (XHR) is the original AJAX engine. Modern code uses fetch instead — but XHR is still useful for upload progress events and supporting very old browsers.

The classic shape

JS
const xhr = new XMLHttpRequest();
xhr.open("GET", "/api/users");          // method, url, [async = true]
xhr.responseType = "json";              // also "text", "blob", "arraybuffer", "document"
xhr.setRequestHeader("Accept", "application/json");

xhr.addEventListener("load", () => {
  if (xhr.status >= 200 && xhr.status < 300) {
    console.log(xhr.response);
  } else {
    console.error("HTTP", xhr.status);
  }
});
xhr.addEventListener("error", () => console.error("Network error"));
xhr.send();

What XHR still does better than fetch

NeedWhy XHR wins
Upload progress eventsxhr.upload.onprogress — fetch needs streaming readers.
Synchronous request (legacy)open(…, false). Almost always a bad idea — blocks the UI.
Tight control over partial readsYou can read responseText as it streams.

The state machine

readyStateMeans
0 UNSENTCreated, not opened.
1 OPENEDopen() called.
2 HEADERS_RECEIVEDResponse headers in.
3 LOADINGBody streaming.
4 DONEFinished — success or error.

Upload progress example

JS
const xhr = new XMLHttpRequest();
xhr.open("POST", "/upload");
xhr.upload.addEventListener("progress", (e) => {
  if (e.lengthComputable) {
    const pct = (e.loaded / e.total) * 100;
    bar.style.width = `${pct}%`;
  }
});
xhr.send(new FormData(form));
Tip: Default to fetch. Reach for XHR only for upload progress bars or rare legacy use cases — the codebase will be cleaner.

Example

Example
<!DOCTYPE html>
<html>
<body>

<p id="out"></p>

<script>
document.getElementById("out").textContent = "Hello from AJAX XMLHttp!";
</script>

</body>
</html>
Try it Yourself »

Exercise

Create the legacy AJAX object.

const xhr = new ();

Test yourself

Q1. XHR's readyState === 4 means…
Q2. XHR still beats fetch for…
Q3. Set a response parsing type with…

Discussion

Loading…