Handling Responses
XHR Response Properties
When an XHR request completes, several properties on the object give you access to the response data:
responseText— the response body as a plain string (always available).responseXML— the response parsed as an XML document (only when Content-Type is XML).response— the response body in the format specified byresponseType.responseType— set this before sending to tell XHR how to parse the response:"","text","json","blob","arraybuffer","document".status— the HTTP status code (200, 404, 500, etc.).statusText— the HTTP status message ("OK", "Not Found", etc.).
// ---- Parsing JSON with responseType ----
const xhrJson = new XMLHttpRequest();
xhrJson.open('GET', '/api/users', true);
xhrJson.responseType = 'json'; // browser parses JSON automatically
xhrJson.onload = function () {
// xhr.response is already a JS object — no JSON.parse() needed
console.log(xhrJson.response[0].name);
};
xhrJson.send();
// ---- Parsing JSON manually from responseText ----
const xhrText = new XMLHttpRequest();
xhrText.open('GET', '/api/users', true);
xhrText.onload = function () {
try {
const users = JSON.parse(xhrText.responseText);
console.log(users);
} catch (e) {
console.error('Invalid JSON:', e.message);
}
};
xhrText.send();
// ---- Parsing XML ----
const xhrXml = new XMLHttpRequest();
xhrXml.open('GET', '/api/data.xml', true);
xhrXml.onload = function () {
const xmlDoc = xhrXml.responseXML;
const items = xmlDoc.getElementsByTagName('item');
Array.from(items).forEach(item => {
console.log(item.textContent);
});
};
xhrXml.send();
HTTP Status Codes
Always check the HTTP status code before processing the response. A completed XHR request (readyState 4) does not mean the request was successful.
| Code | Meaning | Action |
|---|---|---|
| 200 | OK | Process the response normally. |
| 201 | Created | Resource was created successfully. |
| 204 | No Content | Success but no body (common for DELETE). |
| 400 | Bad Request | Client sent invalid data. |
| 401 | Unauthorized | Authentication required. |
| 403 | Forbidden | Authenticated but not allowed. |
| 404 | Not Found | Resource does not exist. |
| 500 | Internal Server Error | Server-side bug. |
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/resource/42', true);
xhr.responseType = 'json';
xhr.onload = function () {
switch (true) {
case xhr.status >= 200 && xhr.status < 300:
console.log('Success:', xhr.response);
break;
case xhr.status === 400:
console.error('Bad request — check your input data');
break;
case xhr.status === 401:
console.warn('Not authenticated — redirect to login');
window.location.href = '/login';
break;
case xhr.status === 403:
console.error('Access denied');
break;
case xhr.status === 404:
console.error('Resource not found');
break;
case xhr.status >= 500:
console.error('Server error — try again later');
break;
default:
console.warn('Unexpected status:', xhr.status);
}
};
xhr.onerror = () => console.error('Network failure');
xhr.send();
// ---- Download an image as a Blob ----
const xhrBlob = new XMLHttpRequest();
xhrBlob.open('GET', '/images/photo.jpg', true);
xhrBlob.responseType = 'blob';
xhrBlob.onload = function () {
const blob = xhrBlob.response;
const url = URL.createObjectURL(blob);
document.getElementById('preview').src = url;
};
xhrBlob.send();
// ---- Download binary data as ArrayBuffer ----
const xhrBuf = new XMLHttpRequest();
xhrBuf.open('GET', '/data/binary.bin', true);
xhrBuf.responseType = 'arraybuffer';
xhrBuf.onload = function () {
const buffer = xhrBuf.response;
const view = new Uint8Array(buffer);
console.log('First byte:', view[0]);
};
xhrBuf.send();
Ready to Level Up Your Skills?
Explore 500+ free tutorials across 20+ languages and frameworks.