What is the difference between XMLHttpRequest and fetch?
The short answer
Both make HTTP requests from the browser, but fetch is the modern replacement. fetch uses promises (cleaner syntax), has a simpler API, and supports streaming. XMLHttpRequest uses callbacks, is more verbose, but supports upload progress events and request cancellation (without AbortController). Use fetch for everything unless you specifically need XHR features.
fetch — the modern way
const response = await fetch('/api/users', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ name: 'John' }),});const data = await response.json();
XMLHttpRequest — the old way
const xhr = new XMLHttpRequest();xhr.open('POST', '/api/users');xhr.setRequestHeader('Content-Type', 'application/json');xhr.onload = function () {const data = JSON.parse(xhr.responseText);};xhr.onerror = function () {console.log('Error');};xhr.send(JSON.stringify({ name: 'John' }));
Key differences
FeaturefetchXMLHttpRequestSyntaxPromise-basedCallback-basedResponse handling.json(), .text(), .blob()Manual parsingError handling.catch() or try/catchonerror callbackStreamingYes (ReadableStream)NoUpload progressNo (need XMLHttpRequest)Yes (xhr.upload.onprogress)CancellationAbortControllerxhr.abort()CookiesNot sent by default (credentials)Sent by defaultHTTP errorsDoes not reject on 404/500Triggers onload for all HTTP responses
When XHR is still useful
The main reason to use XMLHttpRequest today is upload progress:
const xhr = new XMLHttpRequest();xhr.upload.addEventListener('progress', (event) => {const percent = (event.loaded / event.total) * 100;console.log(`${percent}% uploaded`);});
fetch does not have a built-in way to track upload progress (though you can track download progress with ReadableStream).
The fetch gotcha
fetch does not reject on HTTP errors like 404 or 500:
// This does NOT throw for 404const response = await fetch('/not-found');response.ok; // falseresponse.status; // 404// You need to check manuallyif (!response.ok) {throw new Error(`HTTP ${response.status}`);}
Interview Tip
Show both APIs with the same request to highlight the difference in verbosity. Mention the response.ok gotcha with fetch — this is a common interview follow-up. Knowing that XHR is still useful for upload progress shows you have real experience with file uploads.
Why interviewers ask this
This tests your knowledge of browser APIs and web development history. Interviewers want to see if you know the modern approach (fetch) and understand its limitations compared to the older API.