XML HttpRequest
Loading XML data over HTTP lets a web page pull structured content from a server without a full page reload, using either the classic XMLHttpRequest object or the modern Fetch API.
Why Load XML Over HTTP?
Before JSON became the default data format for the web, XML was the standard way for browsers to exchange structured data with servers. Many legacy systems, RSS/Atom feeds, SOAP web services, and enterprise APIs still return XML today, so knowing how to fetch and parse it remains a practical skill even in a JSON-dominated world.
Two browser mechanisms can retrieve XML asynchronously: the older XMLHttpRequest (XHR) object, and the newer Promise-based Fetch API. Both ultimately hand you raw text or a parsed Document object that you can query with standard DOM methods.
Using XMLHttpRequest
XMLHttpRequest was purpose-built with XML in mind — its very name reflects that history. When a response's Content-Type header is text/xml or application/xml, the browser automatically parses the body into a Document accessible via responseXML, so you never have to parse it yourself.
Fetching XML with XMLHttpRequest
<!DOCTYPE html>
<html>
<body>
<script>
const xhr = new XMLHttpRequest();
xhr.open('GET', '/data/books.xml', true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
const xmlDoc = xhr.responseXML;
const titles = xmlDoc.getElementsByTagName('title');
for (let i = 0; i < titles.length; i++) {
console.log(titles[i].textContent);
}
}
};
xhr.send();
</script>
</body>
</html>Using Fetch with a DOMParser
The Fetch API is promise-based and does not know anything about XML — it only understands text, JSON, and binary blobs. To turn a fetched XML string into a queryable document, you pass it through the browser's built-in DOMParser.
Fetching and parsing XML with Fetch
<!DOCTYPE html>
<html>
<body>
<script>
fetch('/data/books.xml')
.then(response => response.text())
.then(xmlText => {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlText, 'application/xml');
const titles = xmlDoc.querySelectorAll('title');
titles.forEach(node => console.log(node.textContent));
})
.catch(error => console.error('Fetch failed:', error));
</script>
</body>
</html>Because DOMParser returns a real Document, you can use familiar DOM methods on it: getElementsByTagName, querySelector, querySelectorAll, and childNodes traversal all work exactly as they would on an HTML page.
Async/Await Version
Fetching XML with async/await
<!DOCTYPE html>
<html>
<body>
<script>
async function loadBooks(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error('HTTP error: ' + response.status);
}
const xmlText = await response.text();
const xmlDoc = new DOMParser().parseFromString(xmlText, 'application/xml');
return xmlDoc.querySelectorAll('book');
}
loadBooks('/data/books.xml').then(books => {
console.log('Loaded ' + books.length + ' books');
});
</script>
</body>
</html>Detecting Parse Errors
DOMParser never throws on malformed XML. Instead, it silently returns a document whose root element is <parsererror>. Always check for this element before trusting the parsed result.
- Check xmlDoc.getElementsByTagName('parsererror').length before using the document
- Prefer response.ok and response.status checks with fetch to catch HTTP-level failures early
- Wrap XHR and fetch calls in try/catch or .catch() to handle network failures
- Set a request timeout for XHR (xhr.timeout) to avoid hanging on unresponsive servers
- Confirm the server sends a correct Content-Type so responseXML is populated automatically
Exercise: XML HttpRequest
What is the main purpose of the XMLHttpRequest object?