This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
* Some parts of this feature may have varying levels of support.
Note: This feature is available in Web Workers, except for Service Workers.
The XMLHttpRequest API enables web apps to make HTTP requests to web servers and receive the responses programmatically using JavaScript. This in turn enables a website to update just part of a page with data from the server, rather than having to navigate to a whole new page. This practice is also sometimes known as AJAX.
The Fetch API is the more flexible and powerful replacement for the XMLHttpRequest API. The Fetch API uses promises instead of events to handle asynchronous responses, integrates well with service workers, and supports advanced aspects of HTTP such as CORS. For these reasons, the Fetch API is usually used in modern web apps instead of XMLHttpRequest.
The central interface in the XMLHttpRequest API is XMLHttpRequest. To make an HTTP request:
XMLHttpRequest instance by calling its constructor.XMLHttpRequest.open(). At this point you provide the URL for the request, the HTTP method to use, and optionally, a username and password.load event is fired when the request has successfully completed, and the error event is fired in various error conditions.XMLHttpRequest.send().For an in-depth guide to the XMLHttpRequest API, see Using XMLHttpRequest.
FormDataAn object representing <form> fields and their values, which can be sent to a server using XMLHttpRequest or fetch().
ProgressEventA subclass of Event which is passed into the progress, and which contains information about how much of the request has been completed.
XMLHttpRequestRepresents a single HTTP request.
XMLHttpRequestEventTargetA superclass of both XMLHttpRequest and XMLHttpRequestUpload, defining the events that are available in both of those interfaces.
XMLHttpRequestUploadRepresents the upload process for an HTTP upload. Provides events enabling code to track the progress of an upload.
In this example we fetch a JSON file from https://raw.githubusercontent.com/mdn/content/main/files/en-us/_wikihistory.json, adding event listeners to show the progress of the event.
<div class="controls"> <button class="xhr" type="button">Click to start XHR</button> </div> <textarea readonly class="event-log"></textarea>
const xhrButton = document.querySelector(".xhr");
const log = document.querySelector(".event-log");
const url =
"https://raw.githubusercontent.com/mdn/content/main/files/en-us/_wikihistory.json";
function handleEvent(e) {
log.textContent = `${log.textContent}${e.type}: ${e.loaded} bytes transferred\n`;
}
function addListeners(xhr) {
xhr.addEventListener("loadstart", handleEvent);
xhr.addEventListener("load", handleEvent);
xhr.addEventListener("loadend", handleEvent);
xhr.addEventListener("progress", handleEvent);
xhr.addEventListener("error", handleEvent);
xhr.addEventListener("abort", handleEvent);
}
xhrButton.addEventListener("click", () => {
log.textContent = "";
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
addListeners(xhr);
xhr.send();
});
| Specification |
|---|
| XMLHttpRequest> |
| Desktop | Mobile | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android | WebView on iOS | |
XMLHttpRequest |
1 | 12 | 1 | ≤12.1 | 3 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 | 1 |
XMLHttpRequest_API |
1 | 12 | 1 | 8 | 1.2 | 18 | 4 | 10.1 | 1 | 1.0 | 3 | 1 |
abort |
1 | 12 | 1 | ≤12.1 | 1.2 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 | 1 |
abort_event |
1 | 12 | 3.5 | ≤12.1 | 1.3 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 | 1 |
authorization_removed_cross_origin |
No | No | 111 | No | 16.1 | No | 111 | No | 16.1 | No | No | 16.1 |
error_event |
1 | 12 | 1 | ≤12.1 | 1.3 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 | 1 |
getAllResponseHeaders |
1 | 12 | 1Starting from Firefox 49, empty headers are returned as empty strings in case the preferencenetwork.http.keep_empty_response_headers_as_empty_string is set to true, defaulting to false. Before Firefox 49 empty headers had been ignored. Since Firefox 50 the preference defaults to true. |
≤12.1 | 1.2 | 18 | 4Starting from Firefox for Android 49, empty headers are returned as empty strings in case the preferencenetwork.http.keep_empty_response_headers_as_empty_string is set to true, defaulting to false. Before Firefox for Android 49 empty headers had been ignored. Since Firefox for Android 50 the preference defaults to true. |
≤12.1 | 1 | 1.0 | 4.4 | 1 |
getResponseHeader |
1 | 12 | 1Starting from Firefox 49, empty headers are returned as empty strings in case the preferencenetwork.http.keep_empty_response_headers_as_empty_string is set to true, defaulting to false. Before Firefox 49 empty headers had been ignored. Since Firefox 50 the preference defaults to true. |
8 | 1.2 | 18 | 4Starting from Firefox for Android 49, empty headers are returned as empty strings in case the preferencenetwork.http.keep_empty_response_headers_as_empty_string is set to true, defaulting to false. Before Firefox for Android 49 empty headers had been ignored. Since Firefox for Android 50 the preference defaults to true. |
10.1 | 1 | 1.0 | 4.4 | 1 |
load_event |
1 | 12 | 1 | ≤12.1 | 1.3 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 | 1 |
loadend_event |
18 | 12 | 5 | ≤12.1 | 4 | 18 | 5 | ≤12.1 | 3 | 1.0 | 4.4 | 3 |
loadstart_event |
1 | 12 | 3.5 | ≤12.1 | 1.3 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 | 1 |
open |
1 | 12 | 1Starting in Firefox 30, synchronous requests on the main thread have been deprecated due to their negative impact on performance and the user experience. Therefore, theasync parameter may not be false except in a Worker. |
8 | 1.2 | 18 | 4Starting in Firefox for Android 30, synchronous requests on the main thread have been deprecated due to their negative impact on performance and the user experience. Therefore, theasync parameter may not be false except in a Worker. |
10.1 | 1 | 1.0 | 4.4 | 1 |
overrideMimeType |
1 | 12 | 1 | ≤12.1 | 1.2 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 | 1 |
progress_event |
1 | 12 | 1 | ≤12.1 | 3 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 | 1 |
readyState |
1 | 12 | 1 | 8 | 1.2 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 | 1 |
readystatechange_event |
1 | 12 | 1 | 9 | 1.2 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 | 1 |
response |
9 | 12 | 6 | 11.6 | 5.1 | 18 | 6 | 12 | 5 | 1.0 | 3 | 5 |
responseText |
1 | 12 | 1 | 8 | 1.2 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 | 1 |
responseType |
31 | 12 | 6 | 1812–15 | 5.1 | 31 | 50 | 1812–14 | 5 | 2.0 | 4.4.3 | 5 |
responseURL |
37 | 14 | 32 | 24 | 8 | 37 | 32 | 24 | 8 | 3.0 | 37 | 8 |
responseXML |
1 | 12 | 1Before Firefox 51, an error parsing the received data added a<parsererror> node to the top of the Document and then returned the Document in whatever state it happens to be in. This was inconsistent with the specification. Starting with Firefox 51, this scenario now correctly returns null as per the spec. |
≤12.1 | 3 | 18 | 4Before Firefox for Android 51, an error parsing the received data added a<parsererror> node to the top of the Document and then returned the Document in whatever state it happens to be in. This was inconsistent with the specification. Starting with Firefox for Android 51, this scenario now correctly returns null as per the spec. |
≤12.1 | 1 | 1.0 | 4.4 | 1 |
send |
1 | 12 | 1 | 8 | 1.2 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 | 1 |
setAttributionReporting |
125 | 125 | No | 111 | No | 125 | No | 83 | No | 27.0 | 125 | No |
setPrivateToken |
117 | 117 | No | 103 | No | 117 | No | 78 | No | 24.0 | 117 | No |
setRequestHeader |
1 | 12 | 1 | 8 | 1.2 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 | 1 |
status |
1 | 12 | 1 | 8 | 1.2 | 18 | 4 | 10.1 | 1 | 1.0 | 4.4 | 1 |
statusText |
1 | 12 | 1 | ≤12.1 | 1.2 | 18 | 4 | ≤12.1 | 1 | 1.0 | 4.4 | 1 |
timeout |
29 | 12 | 12 | 1712–16 | 7 | 29 | 14 | 1812–16 | 7 | 2.0 | 4.4 | 7 |
timeout_event |
29 | 12 | 12 | 16 | 7 | 29 | 14 | 16 | 7 | 1.0 | 4.4 | 7 |
upload |
2 | 12 | 3.5 | ≤12.1 | 4 | 18 | 4 | ≤12.1 | 3 | 1.0 | 4.4 | 3 |
withCredentials |
3 | 12 | 3.5Starting with Firefox 11, it's no longer supported to use thewithCredentials attribute when performing synchronous requests. Attempting to do so throws an NS_ERROR_DOM_INVALID_ACCESS_ERR exception. |
12 | 4 | 18 | 4Starting with Firefox for Android 14, it's no longer supported to use thewithCredentials attribute when performing synchronous requests. Attempting to do so throws an NS_ERROR_DOM_INVALID_ACCESS_ERR exception. |
12 | 3.2 | 1.0 | 4.4 | 3.2 |
worker_support |
4 | 12 | 3.5 | 10.6 | 4 | 18 | 4 | 11 | 5 | 1.0 | 4 | 5 |
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest_API