XMLHttpRequest
What is XMLHttpRequest?
XMLHttpRequest (XHR) is a built-in browser object that enables JavaScript to make HTTP requests to a server without reloading the page. It was originally developed by Microsoft for Internet Explorer 5 and later standardized by the W3C. Despite its name, XHR can transfer any type of data — not just XML.
// 1. Create the XHR object
const xhr = new XMLHttpRequest();
// 2. Configure: open(method, url, async)
// method: 'GET', 'POST', 'PUT', 'DELETE', etc.
// url: the endpoint to call
// async: true (default) = non-blocking
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);
// 3. Set up the response handler
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
const post = JSON.parse(xhr.responseText);
console.log('Title:', post.title);
} else {
console.error('Request failed with status:', xhr.status);
}
};
// 4. Handle network errors
xhr.onerror = function () {
console.error('Network error occurred');
};
// 5. Send the request
xhr.send();
readyState Values
The readyState property tracks the state of the XHR request through its lifecycle. It changes from 0 to 4 as the request progresses.
| Value | State | Description |
|---|---|---|
| 0 | UNSENT | Object created, open() not called yet. |
| 1 | OPENED | open() called, request not sent yet. |
| 2 | HEADERS_RECEIVED | send() called, response headers received. |
| 3 | LOADING | Response body is being downloaded. |
| 4 | DONE | Request complete (success or failure). |
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/users', true);
// onreadystatechange fires every time readyState changes
xhr.onreadystatechange = function () {
console.log('readyState:', xhr.readyState);
if (xhr.readyState === XMLHttpRequest.DONE) { // === 4
if (xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log('Data:', data);
} else {
console.error('Error:', xhr.status, xhr.statusText);
}
}
};
xhr.send();
Timeout and Abort
You can set a timeout (in milliseconds) to automatically cancel a request that takes too long. The abort() method lets you cancel a request programmatically.
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/slow-endpoint', true);
// Cancel request if it takes more than 5 seconds
xhr.timeout = 5000;
xhr.ontimeout = function () {
console.warn('Request timed out after 5 seconds');
};
// Send cookies and auth headers with cross-origin requests
xhr.withCredentials = true;
xhr.onload = function () {
if (xhr.status === 200) {
console.log(xhr.responseText);
}
};
xhr.send();
// Manually cancel the request (e.g., user navigates away)
document.getElementById('cancel-btn').addEventListener('click', () => {
xhr.abort();
console.log('Request aborted');
});
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/upload', true);
// Track download progress
xhr.onprogress = function (event) {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
console.log(`Download: ${percent}%`);
}
};
// Track upload progress
xhr.upload.onprogress = function (event) {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
document.getElementById('progress-bar').style.width = percent + '%';
}
};
xhr.onload = () => console.log('Upload complete:', xhr.status);
xhr.onerror = () => console.error('Upload failed');
const formData = new FormData(document.getElementById('upload-form'));
xhr.send(formData);
Ready to Level Up Your Skills?
Explore 500+ free tutorials across 20+ languages and frameworks.