XMLHttpRequest

Living Standard — Last Updated

Participate:
GitHub whatwg/xhr (new issue, open issues)
IRC: #whatwg on Freenode
Commits:
GitHub whatwg/xhr/commits
Snapshot as of this commit
@xhrstandard
Tests:
web-platform-tests xhr/ (ongoing work)
Translations (non-normative):
日本語

Abstract

The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server.

1. Introduction

This section is non-normative.

The XMLHttpRequest object is an API for fetching resources.

The name XMLHttpRequest is historical and has no bearing on its functionality.

Some simple code to do something with data from an XML document fetched over the network:

function processData(data) {
  // taking care of data
}

function handler() {
  if(this.status == 200 &&
    this.responseXML != null &&
    this.responseXML.getElementById('test').textContent) {
    // success!
    processData(this.responseXML.getElementById('test').textContent);
  } else {
    // something went wrong}
}

var client = new XMLHttpRequest();
client.onload = handler;
client.open("GET", "unicorn.xml");
client.send();

If you just want to log a message to the server:

function log(message) {
  var client = new XMLHttpRequest();
  client.open("POST", "/log");
  client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
  client.send(message);
}

Or if you want to check the status of a document on the server:

function fetchStatus(address) {
  var client = new XMLHttpRequest();
  client.onload = function() {
    // in case of network errors this might not give reliable results
    returnStatus(this.status);
  }
  client.open("HEAD", address);
  client.send();
}

1.1. Specification history

The XMLHttpRequest object was initially defined as part of the WHATWG’s HTML effort. (Based on Microsoft’s implementation many years prior.) It moved to the W3C in 2006. Extensions (e.g., progress events and cross-origin requests) to XMLHttpRequest were developed in a separate draft (XMLHttpRequest Level 2) until end of 2011, at which point the two drafts were merged and XMLHttpRequest became a single entity again from a standards perspective. End of 2012 it moved back to the WHATWG.

Discussion that led to the current draft can be found in the following mailing list archives:

2. Terminology

This specification depends on the Infra Standard. [INFRA]

This specification uses terminology from DOM, DOM Parsing and Serialization, Encoding, Feature Policy, Fetch, File API, HTML, URL, Web IDL, and XML.

[DOM] [DOM-PARSING] [ENCODING] [FEATURE-POLICY] [FETCH] [FILEAPI] [HTML] [URL] [WEBIDL] [XML] [XML-NAMES]

3. Interface XMLHttpRequest

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequestEventTarget : EventTarget {
  // event handlers
  attribute EventHandler onloadstart;
  attribute EventHandler onprogress;
  attribute EventHandler onabort;
  attribute EventHandler onerror;
  attribute EventHandler onload;
  attribute EventHandler ontimeout;
  attribute EventHandler onloadend;
};

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequestUpload : XMLHttpRequestEventTarget {
};

enum XMLHttpRequestResponseType {
  "",
  "arraybuffer",
  "blob",
  "document",
  "json",
  "text"
};

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
  constructor();

  // event handler
  attribute EventHandler onreadystatechange;

  // states
  const unsigned short UNSENT = 0;
  const unsigned short OPENED = 1;
  const unsigned short HEADERS_RECEIVED = 2;
  const unsigned short LOADING = 3;
  const unsigned short DONE = 4;
  readonly attribute unsigned short readyState;

  // request
  undefined open(ByteString method, USVString url);
  undefined open(ByteString method, USVString url, boolean async, optional USVString? username = null, optional USVString? password = null);
  undefined setRequestHeader(ByteString name, ByteString value);
           attribute unsigned long timeout;
           attribute boolean withCredentials;
  [SameObject] readonly attribute XMLHttpRequestUpload upload;
  undefined send(optional (Document or XMLHttpRequestBodyInit)? body = null);
  undefined abort();

  // response
  readonly attribute USVString responseURL;
  readonly attribute unsigned short status;
  readonly attribute ByteString statusText;
  ByteString? getResponseHeader(ByteString name);
  ByteString getAllResponseHeaders();
  undefined overrideMimeType(DOMString mime);
           attribute XMLHttpRequestResponseType responseType;
  readonly attribute any response;
  readonly attribute USVString responseText;
  [Exposed=Window] readonly attribute Document? responseXML;
};

An XMLHttpRequest object has an associated:

upload object
An XMLHttpRequestUpload object.
state
One of unsent, opened, headers received, loading, and done; initially unsent.
send() flag
A flag, initially unset.
timeout
An unsigned integer, initially 0.
cross-origin credentials
A boolean, initially false.
request method
A method.
request URL
A URL.
author request headers
A header list, initially empty.
request body
Initially null.
synchronous flag
A flag, initially unset.
upload complete flag
A flag, initially unset.
upload listener flag
A flag, initially unset.
timed out flag
A flag, initially unset.
response
A response, initially a network error.
received bytes
A byte sequence, initially the empty byte sequence.
response type
One of the empty string, "arraybuffer", "blob", "document", "json", and "text"; initially the empty string.
response object
An object, failure, or null, initially null.
override MIME type
A MIME type or null, initially null. Can get a value when overrideMimeType() is invoked.

3.1. Constructors

client = new XMLHttpRequest()
Returns a new XMLHttpRequest object.

The new XMLHttpRequest() constructor steps are:

  1. Set this’s upload object to a new XMLHttpRequestUpload object.

3.2. Garbage collection

An XMLHttpRequest object must not be garbage collected if its state is either opened with the send() flag set, headers received, or loading, and it has one or more event listeners registered whose type is one of readystatechange, progress, abort, error, load, timeout, and loadend.

If an XMLHttpRequest object is garbage collected while its connection is still open, the user agent must terminate the ongoing fetch operated by the XMLHttpRequest object.

3.3. Event handlers

The following are the event handlers (and their corresponding event handler event types) that must be supported on objects implementing an interface that inherits from XMLHttpRequestEventTarget as attributes:

event handler event handler event type

XMLHttpRequestEventTarget/onloadstart

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)18IE10+
Firefox for AndroidYesiOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
onloadstart
loadstart
onprogress progress

XMLHttpRequestEventTarget/onabort

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)18IE10+
Firefox for AndroidYesiOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
onabort
abort

XMLHttpRequestEventTarget/onerror

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)18IE10+
Firefox for AndroidYesiOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
onerror
error

XMLHttpRequestEventTarget/onload

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)18IE9+
Firefox for AndroidYesiOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes

XMLHttpRequestEventTarget/onprogress

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)18IE10+
Firefox for AndroidYesiOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
onload
load
ontimeout timeout
onloadend loadend

The following is the event handler (and its corresponding event handler event type) that must be supported as attribute solely by the XMLHttpRequest object:

event handler event handler event type

XMLHttpRequest/onreadystatechange

In all current engines.

Firefox1+Safari1.2+Chrome1+
Opera9+Edge79+
Edge (Legacy)12+IE5+
Firefox for Android4+iOS Safari1+Chrome for Android18+Android WebView1+Samsung Internet1.0+Opera Mobile10.1+
onreadystatechange
readystatechange

3.4. States

XMLHttpRequest/readyState

In all current engines.

Firefox1+Safari1.2+Chrome1+
Opera8+Edge79+
Edge (Legacy)12+IE7+
Firefox for Android4+iOS Safari1+Chrome for Android18+Android WebView1+Samsung Internet1.0+Opera Mobile10.1+
client . readyState

Returns client’s state.

The readyState getter steps are to return the value from the table below in the cell of the second column, from the row where the value in the cell in the first column is this’s state:

unsent UNSENT (numeric value 0) The object has been constructed.
opened OPENED (numeric value 1) The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the fetch can be initiated using the send() method.
headers received HEADERS_RECEIVED (numeric value 2) All redirects (if any) have been followed and all headers of a response have been received.
loading LOADING (numeric value 3) The response body is being received.
done DONE (numeric value 4) The data transfer has been completed or something went wrong during the transfer (e.g., infinite redirects).

3.5. Request

Registering one or more event listeners on an XMLHttpRequestUpload object will result in a CORS-preflight request. (That is because registering an event listener causes the upload listener flag to be set, which in turn causes the use-CORS-preflight flag to be set.)

3.5.1. The open() method

XMLHttpRequest/open

In all current engines.

Firefox1+Safari1.2+Chrome1+
Opera8+Edge79+
Edge (Legacy)12+IE5+
Firefox for Android4+iOS Safari1+Chrome for Android18+Android WebView1+Samsung Internet1.0+Opera Mobile10.1+
client . open(method, url [, async = true [, username = null [, password = null]]])

Sets the request method, request URL, and synchronous flag.

Throws a "SyntaxError" DOMException if either method is not a valid method or url cannot be parsed.

Throws a "SecurityError" DOMException if method is a case-insensitive match for `CONNECT`, `TRACE`, or `TRACK`.

Throws an "InvalidAccessError" DOMException if async is false, current global object is a Window object, and the timeout attribute is not zero or the responseType attribute is not the empty string.

Synchronous XMLHttpRequest outside of workers is in the process of being removed from the web platform as it has detrimental effects to the end user’s experience. (This is a long process that takes many years.) Developers must not pass false for the async argument when current global object is a Window object. User agents are strongly encouraged to warn about such usage in developer tools and may experiment with throwing an "InvalidAccessError" DOMException when it occurs.

The open(method, url) and open(method, url, async, username, password) method steps are:

  1. Let settingsObject be this’s relevant settings object.

  2. If settingsObject has a responsible document and it is not fully active, then throw an "InvalidStateError" DOMException.

  3. If method is not a method, then throw a "SyntaxError" DOMException.

  4. If method is a forbidden method, then throw a "SecurityError" DOMException.

  5. Normalize method.

  6. Let parsedURL be the result of parsing url with settingsObject’s API base URL and settingsObject’s API URL character encoding.

  7. If parsedURL is failure, then throw a "SyntaxError" DOMException.

  8. If the async argument is omitted, set async to true, and set username and password to null.

    Unfortunately legacy content prevents treating the async argument being undefined identical from it being omitted.

  9. If parsedURL’s host is non-null, then:

    1. If the username argument is not null, set the username given parsedURL and username.

    2. If the password argument is not null, set the password given parsedURL and password.

  10. If async is false, the current global object is a Window object, and either this’s timeout is not 0 or this’s response type is not the empty string, then throw an "InvalidAccessError" DOMException.

  11. Terminate the ongoing fetch operated by the XMLHttpRequest object.

    A fetch can be ongoing at this point.

  12. Set variables associated with the object as follows:

    Override MIME type is not overridden here as the overrideMimeType() method can be invoked before the open() method.

  13. If this’s state is not opened, then:

    1. Set this’s state to opened.

    2. Fire an event named readystatechange at this.

The reason there are two open() methods defined is due to a limitation of the editing software used to write the XMLHttpRequest Standard.

3.5.2. The setRequestHeader() method

XMLHttpRequest/setRequestHeader

In all current engines.

Firefox1+Safari1.2+Chrome1+
Opera8+Edge79+
Edge (Legacy)12+IE5+
Firefox for Android4+iOS Safari1+Chrome for Android18+Android WebView1+Samsung Internet1.0+Opera Mobile10.1+
client . setRequestHeader(name, value)

Combines a header in author request headers.

Throws an "InvalidStateError" DOMException if either state is not opened or the send() flag is set.

Throws a "SyntaxError" DOMException if name is not a header name or if value is not a header value.

The setRequestHeader(name, value) method must run these steps:

  1. If this’s state is not opened, then throw an "InvalidStateError" DOMException.

  2. If this’s send() flag is set, then throw an "InvalidStateError" DOMException.

  3. Normalize value.

  4. If name is not a name or value is not a value, then throw a "SyntaxError" DOMException.

    An empty byte sequence represents an empty header value.

  5. If name is a forbidden header name, then return.

  6. Combine name/value in this’s author request headers.

Some simple code demonstrating what happens when setting the same header twice:

// The following script:
var client = new XMLHttpRequest();
client.open('GET', 'demo.cgi');
client.setRequestHeader('X-Test', 'one');
client.setRequestHeader('X-Test', 'two');
client.send();

// …results in the following header being sent:
// X-Test: one, two

3.5.3. The timeout getter and setter

XMLHttpRequest/timeout

In all current engines.

Firefox12+Safari6.1+Chrome29+
Opera17+Edge79+
Edge (Legacy)12+IE8+
Firefox for Android14+iOS Safari7+Chrome for Android29+Android WebView37+Samsung Internet2.0+Opera Mobile18+
client . timeout

Can be set to a time in milliseconds. When set to a non-zero value will cause fetching to terminate after the given time has passed. When the time has passed, the request has not yet completed, and this’s synchronous flag is unset, a timeout event will then be dispatched, or a "TimeoutError" DOMException will be thrown otherwise (for the send() method).

When set: throws an "InvalidAccessError" DOMException if the synchronous flag is set and current global object is a Window object.

The timeout getter steps are to return this’s timeout.

The timeout setter steps are:

  1. If the current global object is a Window object and this’s synchronous flag is set, then throw an "InvalidAccessError" DOMException.

  2. Set this’s timeout to the given value.

This implies that the timeout attribute can be set while fetching is in progress. If that occurs it will still be measured relative to the start of fetching.

3.5.4. The withCredentials getter and setter

XMLHttpRequest/withCredentials

In all current engines.

Firefox3.5+Safari4+Chrome3+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android4+iOS Safari3.2+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile12+
client . withCredentials

True when credentials are to be included in a cross-origin request. False when they are to be excluded in a cross-origin request and when cookies are to be ignored in its response. Initially false.

When set: throws an "InvalidStateError" DOMException if state is not unsent or opened, or if the send() flag is set.

The withCredentials getter steps are to return this’s cross-origin credentials.

The withCredentials setter steps are:

  1. If this’s state is not unsent or opened, then throw an "InvalidStateError" DOMException.

  2. If this’s send() flag is set, then throw an "InvalidStateError" DOMException.

  3. Set this’s cross-origin credentials to the given value.

3.5.5. The upload getter

XMLHttpRequest/upload

In all current engines.

FirefoxYesSafari10+Chrome1+
OperaYesEdge79+
Edge (Legacy)12+IE10+
Firefox for AndroidYesiOS SafariYesChrome for Android18+Android WebViewYesSamsung Internet1.0+Opera MobileYes
client . upload

Returns the associated XMLHttpRequestUpload object. It can be used to gather transmission information when data is transferred to a server.

The upload getter steps are to return this’s upload object.

3.5.6. The send() method

XMLHttpRequest/send

In all current engines.

Firefox1+Safari1.2+Chrome1+
Opera8+Edge79+
Edge (Legacy)12+IE5+
Firefox for Android4+iOS Safari1+Chrome for Android18+Android WebView1+Samsung Internet1.0+Opera Mobile10.1+
client . send([body = null])

Initiates the request. The body argument provides the request body, if any, and is ignored if the request method is GET or HEAD.

Throws an "InvalidStateError" DOMException if either state is not opened or the send() flag is set.

The send(body) method steps are:

  1. If this’s state is not opened, then throw an "InvalidStateError" DOMException.

  2. If this’s send() flag is set, then throw an "InvalidStateError" DOMException.

  3. If this’s request method is `GET` or `HEAD`, then set body to null.

  4. If body is not null, then:

    1. Let extractedContentType be null.

    2. If body is a Document, then set this’s request body to body, serialized, converted, and UTF-8 encoded.

    3. Otherwise, set this’s request body and extractedContentType to the result of safely extracting body.

    4. Let originalAuthorContentType be the result of getting `Content-Type` from this’s author request headers.

    5. If originalAuthorContentType is non-null, then:

      1. If body is a Document or a USVString, then:

        1. Let contentTypeRecord be the result of parsing originalAuthorContentType.

        2. If contentTypeRecord is not failure, contentTypeRecord’s parameters["charset"] exists, and parameters["charset"] is not an ASCII case-insensitive match for "UTF-8", then:

          1. Set contentTypeRecord’s parameters["charset"] to "UTF-8".

          2. Let newContentTypeSerialized be the result of serializing contentTypeRecord.

          3. Set `Content-Type`/newContentTypeSerialized in this’s author request headers.

    6. Otherwise:

      1. If body is an HTML document, set `Content-Type`/`text/html;charset=UTF-8` in this’s author request headers.

      2. Otherwise, if body is an XML document, set `Content-Type`/`application/xml;charset=UTF-8` in this’s author request headers.

      3. Otherwise, if extractedContentType is not null, set `Content-Type`/extractedContentType in this’s author request headers.

  5. If one or more event listeners are registered on this’s upload object, then set this’s upload listener flag.

  6. Let req be a new request, initialized as follows:

    method
    This’s request method.
    URL
    This’s request URL.
    header list
    This’s author request headers.
    unsafe-request flag
    Set.
    body
    This’s request body.
    client
    This’s relevant settings object.
    synchronous flag
    Set if this’s synchronous flag is set.
    mode
    "cors".
    use-CORS-preflight flag
    Set if this’s upload listener flag is set.
    credentials mode
    If this’s cross-origin credentials is true, then "include"; otherwise "same-origin".
    use-URL-credentials flag
    Set if this’s request URL includes credentials.
  7. Unset this’s upload complete flag.

  8. Unset this’s timed out flag.

  9. If req’s body is null, then set this’s upload complete flag.

  10. Set this’s send() flag.

  11. If this’s synchronous flag is unset, then:

    1. Fire a progress event named loadstart at this with 0 and 0.

    2. If this’s upload complete flag is unset and this’s upload listener flag is set, then fire a progress event named loadstart at this’s upload object with 0 and req’s body’s total bytes.

    3. If this’s state is not opened or this’s send() flag is unset, then return.

    4. Fetch req. Handle the tasks queued on the networking task source per below.

      Run these steps in parallel:

      1. Wait until either req’s done flag is set or this’s timeout is not 0 and this’s timeout milliseconds have passed since these steps started.

      2. If req’s done flag is unset, then set this’s timed out flag and terminate fetching.

      To process request body for request, run these steps:

      1. If not roughly 50ms have passed since these steps were last invoked, terminate these steps.

      2. If this’s upload listener flag is set, then fire a progress event named progress at this’s upload object with request’s body’s transmitted bytes and request’s body’s total bytes.

      These steps are only invoked when new bytes are transmitted.

      To process request end-of-body for request, run these steps:

      1. Set this’s upload complete flag.

      2. If this’s upload listener flag is unset, then terminate these steps.

      3. Let transmitted be request’s body’s transmitted bytes.

      4. Let length be request’s body’s total bytes.

      5. Fire a progress event named progress at this’s upload object with transmitted and length.

      6. Fire a progress event named load at this’s upload object with transmitted and length.

      7. Fire a progress event named loadend at this’s upload object with transmitted and length.

      To process response for response, run these steps:

      1. Set this’s response to response.

      2. Handle errors fo this and response.

      3. If this’s response is a network error, then return.

      4. Set this’s state to headers received.

      5. Fire an event named readystatechange at this.

      6. If this’s state is not headers received, then return.

      7. If this’s response’s body is null, then run handle response end-of-body for this and this’s response, and then return.

      8. Let reader be the result of getting a reader for this’s response’s body’s stream.

        This operation will not throw an exception.

      9. Let readRequest be the following read request:

        chunk steps, given chunk
        1. Append chunk to this’s received bytes.

        2. If not roughly 50ms have passed since these steps were last invoked, then abort these steps.

        3. If this’s state is headers received, then set this’s state to loading.

        4. Fire an event named readystatechange at this.

          Web compatibility is the reason readystatechange fires more often than this’s state changes.

        5. Fire a progress event named progress at this with this’s response’s body’s transmitted bytes and this’s response’s body’s total bytes.

        close steps
        1. Run handle response end-of-body for this and this’s response.

        error steps
        1. Run handle errors for this and this’s response.

      10. Read a chunk from reader given readRequest.

  12. Otherwise, if this’s synchronous flag is set:

    1. If this’s relevant settings object has a responsible document which is not allowed to use the "sync-xhr" feature, then run handle response end-of-body for this and a network error, and then return.

    2. Let response be the result of fetching req.

      If this’s timeout is not 0, then set this’s timed out flag and terminate fetching if it has not returned within this’s timeout milliseconds.

    3. If response’s body is null, then run handle response end-of-body for this and response, and then return.

    4. Let reader be the result of getting a reader for response’s body’s stream.

      This operation will not throw an exception.

    5. Let promise be the result of reading all bytes from reader.

    6. Wait for promise to be fulfilled or rejected.

    7. If promise is fulfilled with bytes, then append bytes to this’s received bytes.

    8. Run handle response end-of-body for this and response.

To handle response end-of-body for an XMLHttpRequest object xhr and a response response, run these steps:

  1. If xhr’s synchronous flag is set, then set xhr’s response to response.

  2. Handle errors for xhr and response.

  3. If xhr’s response is a network error, then return.

  4. If xhr’s synchronous flag is unset, then update xhr’s response’s body using response.

  5. Let transmitted be response’s body’s transmitted bytes.

  6. Let length be response’s body’s total bytes.

  7. If xhr’s synchronous flag is unset, then fire a progress event named progress at xhr with transmitted and length.

  8. Set xhr’s state to done.

  9. Unset xhr’s send() flag.

  10. Fire an event named readystatechange at xhr.

  11. Fire a progress event named load at xhr with transmitted and length.

  12. Fire a progress event named loadend at xhr with transmitted and length.

To handle errors for an XMLHttpRequest object xhr and a response response, run these steps:

  1. If xhr’s send() flag is unset, then return.

  2. If xhr’s timed out flag is set, then run the request error steps for xhr, timeout, and "TimeoutError" DOMException.

  3. If response is a network error, then run the request error steps for xhr, error, and "NetworkError" DOMException.

  4. Otherwise, if response’s body’s stream is errored, then:

    1. Set xhr’s state to done.

    2. Unset xhr’s send() flag.

    3. Set xhr’s response to a network error.

  5. Otherwise, if xhr’s response’s aborted flag is set, then run the request error steps for xhr, abort, and "AbortError" DOMException.

The request error steps for an XMLHttpRequest object xhr, event, and optionally exception are:

  1. Set xhr’s state to done.

  2. Unset xhr’s send() flag.

  3. Set xhr’s response to a network error.

  4. If xhr’s synchronous flag is set, then throw exception.

  5. Fire an event named readystatechange at xhr.

    At this point it is clear that xhr’s synchronous flag is unset.

  6. If xhr’s upload complete flag is unset, then:

    1. Set xhr’s upload complete flag.

    2. If xhr’s upload listener flag is set, then:

      1. Fire a progress event named event at xhr’s upload object with 0 and 0.

      2. Fire a progress event named loadend at xhr’s upload object with 0 and 0.

  7. Fire a progress event named event at xhr with 0 and 0.

  8. Fire a progress event named loadend at xhr with 0 and 0.

3.5.7. The abort() method

XMLHttpRequest/abort

In all current engines.

FirefoxYesSafari1.2+Chrome18+
OperaYesEdge79+
Edge (Legacy)12+IE5+
Firefox for AndroidYesiOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
client . abort()
Cancels any network activity.

The abort() method steps are:

  1. Terminate the ongoing fetch with the aborted flag set.

  2. If this’s state is opened with this’s send() flag set, headers received, or loading, then run the request error steps for this and abort.

  3. If this’s state is done, then set this’s state to unsent and this’s response to a network error.

    No readystatechange event is dispatched.

3.6. Response

3.6.1. The responseURL getter

XMLHttpRequest/responseURL

In all current engines.

Firefox32+Safari8+Chrome37+
Opera24+Edge79+
Edge (Legacy)14+IENone
Firefox for Android32+iOS SafariYesChrome for Android37+Android WebView37+Samsung Internet3.0+Opera Mobile24+

The responseURL getter steps are to return the empty string if this’s response’s URL is null; otherwise its serialization with the exclude fragment flag set.

3.6.2. The status getter

XMLHttpRequest/status

In all current engines.

Firefox1+Safari1.2+Chrome1+
Opera8+Edge79+
Edge (Legacy)12+IE7+
Firefox for Android4+iOS Safari1+Chrome for Android18+Android WebView1+Samsung Internet1.0+Opera Mobile10.1+

The status getter steps are to return this’s response’s status.

3.6.3. The statusText getter

XMLHttpRequest/statusText

In all current engines.

Firefox1+Safari1.2+Chrome1+
OperaYesEdge79+
Edge (Legacy)12+IE7+
Firefox for Android4+iOS SafariYesChrome for Android18+Android WebViewYesSamsung Internet1.0+Opera MobileYes

The statusText getter steps are to return this’s response’s status message.

3.6.4. The getResponseHeader() method

XMLHttpRequest/getResponseHeader

In all current engines.

Firefox1+Safari1.2+Chrome1+
Opera8+Edge79+
Edge (Legacy)12+IE5+
Firefox for Android4+iOS Safari1+Chrome for Android18+Android WebView1+Samsung Internet1.0+Opera Mobile10.1+

The getResponseHeader(name) method steps are to return the result of getting name from this’s response’s header list.

The Fetch Standard filters this’s response’s header list. [FETCH]

For the following script:

var client = new XMLHttpRequest();
client.open("GET", "unicorns-are-awesome.txt", true);
client.send();
client.onreadystatechange = function() {
  if(this.readyState == this.HEADERS_RECEIVED) {
    print(client.getResponseHeader("Content-Type"));
  }
}

The print() function will get to process something like:

text/plain; charset=UTF-8

3.6.5. The getAllResponseHeaders() method

XMLHttpRequest/getAllResponseHeaders

In all current engines.

Firefox4+Safari1.2+Chrome1+
OperaYesEdge79+
Edge (Legacy)12+IE5+
Firefox for Android4+iOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes

A byte sequence a is legacy-uppercased-byte less than a byte sequence b if the following steps return true:

  1. Let A be a, byte-uppercased.

  2. Let B be b, byte-uppercased.

  3. Return A is byte less than B.

The getAllResponseHeaders() method steps are:

  1. Let output be an empty byte sequence.

  2. Let initialHeaders be the result of running sort and combine with this’s response’s header list.

  3. Let headers be the result of sorting initialHeaders in ascending order, with a being less than b if a’s name is legacy-uppercased-byte less than b’s name.

    Unfortunately, this is needed for compatibility with deployed content.

  4. For each header in headers, append header’s name, followed by a 0x3A 0x20 byte pair, followed by header’s value, followed by a 0x0D 0x0A byte pair, to output.

  5. Return output.

The Fetch Standard filters this’s response’s header list. [FETCH]

For the following script:

var client = new XMLHttpRequest();
client.open("GET", "narwhals-too.txt", true);
client.send();
client.onreadystatechange = function() {
  if(this.readyState == this.HEADERS_RECEIVED) {
    print(this.getAllResponseHeaders());
  }
}

The print() function will get to process something like:

connection: Keep-Alive
content-type: text/plain; charset=utf-8
date: Sun, 24 Oct 2004 04:58:38 GMT
keep-alive: timeout=15, max=99
server: Apache/1.3.31 (Unix)
transfer-encoding: chunked

3.6.6. Response body

To get a response MIME type for an XMLHttpRequest object xhr, run these steps:

  1. Let mimeType be the result of extracting a MIME type from xhr’s response’s header list.

  2. If mimeType is failure, then set mimeType to text/xml.

  3. Return mimeType.

To get a final MIME type for an XMLHttpRequest object xhr, run these steps:

  1. If xhr’s override MIME type is null, return the result of get a response MIME type for xhr.

  2. Return xhr’s override MIME type.

To get a final encoding for an XMLHttpRequest object xhr, run these steps:

  1. Let label be null.

  2. Let responseMIME be the result of get a response MIME type for xhr.

  3. If responseMIME’s parameters["charset"] exists, then set label to it.

  4. If xhr’s override MIME type’s parameters["charset"] exists, then set label to it.

  5. If label is null, then return null.

  6. Let encoding be the result of getting an encoding from label.

  7. If encoding is failure, then return null.

  8. Return encoding.

The above steps intentionally do not use the get a final MIME type as it would not be web compatible.


To set a document response for an XMLHttpRequest object xhr, run these steps:

  1. If xhr’s response’s body is null, then return.

  2. Let finalMIME be the result of get a final MIME type for xhr.

  3. If finalMIME is not an HTML MIME type or an XML MIME type, then return.

  4. If xhr’s response type is the empty string and finalMIME is an HTML MIME type, then return.

    This is restricted to xhr’s response type being "document" in order to prevent breaking legacy content.

  5. If finalMIME is an HTML MIME type, then:

    1. Let charset be the result of get a final encoding for xhr.

    2. If charset is null, prescan the first 1024 bytes of xhr’s received bytes and if that does not terminate unsuccessfully then let charset be the return value.

    3. If charset is null, then set charset to UTF-8.

    4. Let document be a document that represents the result parsing xhr’s received bytes following the rules set forth in the HTML Standard for an HTML parser with scripting disabled and a known definite encoding charset. [HTML]

    5. Flag document as an HTML document.

  6. Otherwise, let document be a document that represents the result of running the XML parser with XML scripting support disabled on xhr’s received bytes. If that fails (unsupported character encoding, namespace well-formedness error, etc.), then return null. [HTML]

    Resources referenced will not be loaded and no associated XSLT will be applied.

  7. If charset is null, then set charset to UTF-8.

  8. Set document’s encoding to charset.

  9. Set document’s content type to finalMIME.

  10. Set document’s URL to xhr’s response’s URL.

  11. Set document’s origin to xhr’s relevant settings object’s origin.

  12. Set xhr’s response object to document.

To get a text response for an XMLHttpRequest object xhr, run these steps:

  1. If xhr’s response’s body is null, then return the empty string.

  2. Let charset be the result of get a final encoding for xhr.

  3. If xhr’s response type is the empty string, charset is null, and the result of get a final MIME type for xhr is an XML MIME type, then use the rules set forth in the XML specifications to determine the encoding. Let charset be the determined encoding. [XML] [XML-NAMES]

    This is restricted to xhr’s response type being the empty string to keep the non-legacy response type value "text" simple.

  4. If charset is null, then set charset to UTF-8.

  5. Return the result of running decode on xhr’s received bytes using fallback encoding charset.

Authors are strongly encouraged to always encode their resources using UTF-8.

3.6.7. The overrideMimeType() method

XMLHttpRequest/overrideMimeType

In all current engines.

FirefoxYesSafari1.2+Chrome1+
OperaYesEdge79+
Edge (Legacy)12+IE11
Firefox for AndroidYesiOS SafariYesChrome for Android18+Android WebViewYesSamsung Internet1.0+Opera MobileYes
client . overrideMimeType(mime)

Acts as if the `Content-Type` header value for a response is mime. (It does not change the header.)

Throws an "InvalidStateError" DOMException if state is loading or done.

The overrideMimeType(mime) method steps are:

  1. If this’s state is loading or done, then throw an "InvalidStateError" DOMException.

  2. Set this’s override MIME type to the result of parsing mime.

  3. If this’s override MIME type is failure, then set this’s override MIME type to application/octet-stream.

3.6.8. The responseType getter and setter

XMLHttpRequest/responseType

In all current engines.

Firefox6+Safari7+Chrome31+
Opera18+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android50+iOS Safari7+Chrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+
client . responseType [ = value ]

Returns the response type.

Can be set to change the response type. Values are: the empty string (default), "arraybuffer", "blob", "document", "json", and "text".

When set: setting to "document" is ignored if current global object is not a Window object.

When set: throws an "InvalidStateError" DOMException if state is loading or done.

When set: throws an "InvalidAccessError" DOMException if the synchronous flag is set and current global object is a Window object.

The responseType getter steps are to return this’s response type.

The responseType setter steps are:

  1. If the current global object is not a Window object and the given value is "document", then return.

  2. If this’s state is loading or done, then throw an "InvalidStateError" DOMException.

  3. If the current global object is a Window object and this’s synchronous flag is set, then throw an "InvalidAccessError" DOMException.

  4. Set this’s response type to the given value.

3.6.9. The response getter

XMLHttpRequest/response

In all current engines.

Firefox6+Safari5.1+Chrome9+
Opera11.6+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android6+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile12+
client . response

Returns the response body.

The response getter steps are:

  1. If this’s response type is the empty string or "text", then:

    1. If this’s state is not loading or done, then return the empty string.

    2. Return the result of getting a text response for this.

  2. If this’s state is not done, then return null.

  3. If this’s response object is failure, then return null.

  4. If this’s response object is non-null, then return it.

  5. If this’s response type is "arraybuffer", then set this’s response object to a new ArrayBuffer object representing this’s received bytes. If this throws an exception, then set this’s response object to failure and return null.

    Allocating an ArrayBuffer object is not guaranteed to succeed. [ECMASCRIPT]

  6. Otherwise, if this’s response type is "blob", set this’s response object to a new Blob object representing this’s received bytes with type set to the result of get a final MIME type for this.

  7. Otherwise, if this’s response type is "document", set a document response for this.

  8. Otherwise:

    1. Assert: this’s response type is "json".

    2. If this’s response’s body is null, then return null.

    3. Let jsonObject be the result of running parse JSON from bytes on this’s received bytes. If that threw an exception, then return null.

    4. Set this’s response object to jsonObject.

  9. Return this’s response object.

3.6.10. The responseText getter

XMLHttpRequest/responseText

In all current engines.

Firefox1+Safari1.2+Chrome1+
Opera8+Edge79+
Edge (Legacy)12+IE5+
Firefox for Android4+iOS Safari1+Chrome for Android18+Android WebView1+Samsung Internet1.0+Opera Mobile10.1+
client . responseText

Returns response as text.

Throws an "InvalidStateError" DOMException if responseType is not the empty string or "text".

The responseText getter steps are:

  1. If this’s response type is not the empty string or "text", then throw an "InvalidStateError" DOMException.

  2. If this’s state is not loading or done, then return the empty string.

  3. Return the result of getting a text response for this.

3.6.11. The responseXML getter

XMLHttpRequest/responseXML

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)12+IEYes
Firefox for AndroidYesiOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
client . responseXML

Returns the response as document.

Throws an "InvalidStateError" DOMException if responseType is not the empty string or "document".

The responseXML getter steps are:

  1. If this’s response type is not the empty string or "document", then throw an "InvalidStateError" DOMException.

  2. If this’s state is not done, then return null.

  3. Assert: this’s response object is not failure.

  4. If this’s response object is non-null, then return it.

  5. Set a document response for this.

  6. Return this’s response object.

3.7. Events summary

This section is non-normative.

The following events are dispatched on XMLHttpRequest or XMLHttpRequestUpload objects:

Event name Interface Dispatched when…
readystatechange Event The readyState attribute changes value, except when it changes to UNSENT.

XMLHttpRequest/loadstart_event

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)NoneIE10+
Firefox for AndroidYesiOS Safari?Chrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
loadstart
ProgressEvent The fetch initiates.

XMLHttpRequest/progress_event

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)NoneIE10+
Firefox for AndroidYesiOS Safari?Chrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
progress
ProgressEvent Transmitting data.

XMLHttpRequest/abort_event

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)NoneIE10+
Firefox for AndroidYesiOS Safari?Chrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
abort
ProgressEvent When the fetch has been aborted. For instance, by invoking the abort() method.

XMLHttpRequest/error_event

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)NoneIE10+
Firefox for AndroidYesiOS Safari?Chrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
error
ProgressEvent The fetch failed.

XMLHttpRequest/load_event

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)NoneIE9+
Firefox for AndroidYesiOS Safari?Chrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
load
ProgressEvent The fetch succeeded.

XMLHttpRequest/timeout_event

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)18IE10+
Firefox for AndroidYesiOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
timeout
ProgressEvent The author specified timeout has passed before the fetch completed.

XMLHttpRequest/loadend_event

In all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)NoneIE10+
Firefox for AndroidYesiOS Safari?Chrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
loadend
ProgressEvent The fetch completed (success or failure).

3.8. Feature Policy integration

Headers/Feature-Policy/sync-xhr

In only one current engine.

FirefoxNoneSafariNoneChrome65+
Opera52+Edge79+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android65+Android WebView65+Samsung Internet9.0+Opera Mobile47+

This specification defines a policy-controlled feature identified by the string "sync-xhr". Its default allowlist is *.

4. Interface FormData

FormData

In all current engines.

Firefox4+Safari5+Chrome7+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android4+iOS Safari5+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile12+
typedef (File or USVString) FormDataEntryValue;

[Exposed=(Window,Worker)]
interface FormData {
  constructor(optional HTMLFormElement form);

  undefined append(USVString name, USVString value);
  undefined append(USVString name, Blob blobValue, optional USVString filename);
  undefined delete(USVString name);
  FormDataEntryValue? get(USVString name);
  sequence<FormDataEntryValue> getAll(USVString name);
  boolean has(USVString name);
  undefined set(USVString name, USVString value);
  undefined set(USVString name, Blob blobValue, optional USVString filename);
  iterable<USVString, FormDataEntryValue>;
};

Each FormData object has an associated entry list (a list of entries). It is initially the empty list.

An entry consists of a name and a value.

For the purposes of interaction with other algorithms, an entry’s filename is the empty string if value is not a File object, and otherwise its filename is the value of entry’s value’s name attribute.

To create an entry for name, value, and optionally a filename, run these steps:

  1. Let entry be a new entry.

  2. Set entry’s name to name.

  3. If value is a Blob object and not a File object, then set value to a new File object, representing the same bytes, whose name attribute value is "blob".

  4. If value is (now) a File object and filename is given, then set value to a new File object, representing the same bytes, whose name attribute value is filename.

  5. Set entry’s value to value.

  6. Return entry.


FormData/FormData

In all current engines.

Firefox4+Safari5+Chrome7+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android4+iOS Safari5+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile12+

FormData/entries

In all current engines.

Firefox44+Safari11+Chrome50+
Opera37+Edge79+
Edge (Legacy)18IENone
Firefox for Android44+iOS Safari11+Chrome for Android50+Android WebView50+Samsung Internet5.0+Opera Mobile37+

FormData/keys

In all current engines.

Firefox44+Safari11+Chrome50+
OperaYesEdge79+
Edge (Legacy)18IENone
Firefox for Android44+iOS Safari11+Chrome for Android50+Android WebView50+Samsung Internet5.0+Opera Mobile?

FormData/values

In all current engines.

Firefox44+Safari11+Chrome50+
Opera37+Edge79+
Edge (Legacy)18IENone
Firefox for Android44+iOS Safari11+Chrome for Android50+Android WebView50+Samsung Internet5.0+Opera Mobile37+

The new FormData(form) constructor steps are:

  1. If form is given, then:

    1. Let list be the result of constructing the entry list for form.

    2. If list is null, then throw an "InvalidStateError" DOMException.

    3. Set this’s entry list to list.

FormData/append

In all current engines.

Firefox4+Safari5+Chrome7+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android4+iOS Safari5+Chrome for Android18+Android WebView3+Samsung Internet1.0+Opera Mobile12+

The append(name, value) and append(name, blobValue, filename) method steps are:

  1. Let value be value if given; otherwise blobValue.

  2. Let entry be the result of creating an entry with name, value, and filename if given.

  3. Append entry to this’s entry list.

The reason there is an argument named value as well as blobValue is due to a limitation of the editing software used to write the XMLHttpRequest Standard.

FormData/delete

In all current engines.

Firefox39+Safari11+Chrome50+
OperaYesEdge79+
Edge (Legacy)18IENone
Firefox for AndroidYesiOS SafariNoneChrome for Android50+Android WebViewYesSamsung Internet5.0+Opera MobileYes

The delete(name) method steps are to remove all entries whose name is name from this’s entry list.

FormData/get

In all current engines.

Firefox39+Safari11+Chrome50+
Opera37+Edge79+
Edge (Legacy)18IENone
Firefox for Android39+iOS Safari11+Chrome for Android50+Android WebView50+Samsung Internet5.0+Opera Mobile37+

The get(name) method steps are:

  1. If there is no entry whose name is name in this’s entry list, then return null.

  2. Return the value of the first entry whose name is name from this’s entry list.

FormData/getAll

In all current engines.

Firefox39+Safari11+Chrome50+
Opera37+Edge79+
Edge (Legacy)18IENone
Firefox for Android39+iOS Safari11+Chrome for Android50+Android WebView50+Samsung Internet5.0+Opera Mobile37+

The getAll(name) method steps are:

  1. If there is no entry whose name is name in this’s entry list, then return the empty list.

  2. Return the values of all entries whose name is name, in order, from this’s entry list.

FormData/has

In all current engines.

Firefox39+Safari11+Chrome50+
OperaYesEdge79+
Edge (Legacy)18IENone
Firefox for AndroidYesiOS SafariNoneChrome for Android50+Android WebViewYesSamsung Internet5.0+Opera MobileYes

The has(name) method steps are to return true if there is an entry whose name is name in this’s entry list; otherwise false.

FormData/set

In all current engines.

Firefox39+Safari11+Chrome50+
Opera37+Edge79+
Edge (Legacy)18IENone
Firefox for Android39+iOS Safari11+Chrome for Android50+Android WebView50+Samsung Internet5.0+Opera Mobile37+

The set(name, value) and set(name, blobValue, filename) method steps are:

  1. Let value be value if given; otherwise blobValue.

  2. Let entry be the result of creating an entry with name, value, and filename if given.

  3. If there are entries in this’s entry list whose name is name, then replace the first such entry with entry and remove the others.

  4. Otherwise, append entry to this’s entry list.

The reason there is an argument named value as well as blobValue is due to a limitation of the editing software used to write the XMLHttpRequest Standard.

The value pairs to iterate over are this’s entry list’s entries with the key being the name and the value being the value.

5. Interface ProgressEvent

ProgressEvent

In all current engines.

Firefox3.5+SafariYesChrome1+
OperaYesEdge79+
Edge (Legacy)12+IE10+
Firefox for Android4+iOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes

ProgressEvent/ProgressEvent

In all current engines.

Firefox22+SafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)NoneIENone
Firefox for Android22+iOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes
[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface ProgressEvent : Event {
  constructor(DOMString type, optional ProgressEventInit eventInitDict = {});

  readonly attribute boolean lengthComputable;
  readonly attribute unsigned long long loaded;
  readonly attribute unsigned long long total;
};

dictionary ProgressEventInit : EventInit {
  boolean lengthComputable = false;
  unsigned long long loaded = 0;
  unsigned long long total = 0;
};

Events using the ProgressEvent interface indicate some kind of progression.

ProgressEvent/lengthComputable

In all current engines.

Firefox3.5+Safari3.1+Chrome50+
Opera37+Edge79+
Edge (Legacy)12+IEYes
Firefox for Android4+iOS Safari2+Chrome for Android50+Android WebView50+Samsung Internet5.0+Opera Mobile37+

ProgressEvent/loaded

In all current engines.

Firefox3.5+SafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)12+IENone
Firefox for Android4+iOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes

ProgressEvent/total

In all current engines.

Firefox3.5+SafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)12+IENone
Firefox for Android4+iOS SafariYesChrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes

The lengthComputable, loaded, and total getter steps are to return the value they were initialized to.

5.1. Firing events using the ProgressEvent interface

To fire a progress event named e at target, given transmitted and length, means to fire an event named e at target, using ProgressEvent, with the loaded attribute initialized to transmitted, and if length is not 0, with the lengthComputable attribute initialized to true and the total attribute initialized to length.

5.2. Suggested names for events using the ProgressEvent interface

This section is non-normative.

The suggested type attribute values for use with events using the ProgressEvent interface are summarized in the table below. Specification editors are free to tune the details to their specific scenarios, though are strongly encouraged to discuss their usage with the WHATWG community to ensure input from people familiar with the subject.

type attribute value Description Times When
loadstart Progress has begun. Once. First.
progress In progress. Once or more. After loadstart has been dispatched.
error Progression failed. Zero or once (mutually exclusive). After the last progress has been dispatched.
abort Progression is terminated.
timeout Progression is terminated due to preset time expiring.
load Progression is successful.
loadend Progress has stopped. Once. After one of error, abort, timeout or load has been dispatched.

The error, abort, timeout, and load event types are mutually exclusive.

Throughout the web platform the error, abort, timeout and load event types have their bubbles and cancelable attributes initialized to false, so it is suggested that for consistency all events using the ProgressEvent interface do the same.

5.3. Security considerations

For cross-origin requests some kind of opt-in, e.g., the CORS protocol defined in the Fetch Standard, has to be used before events using the ProgressEvent interface are dispatched as information (e.g., size) would be revealed that cannot be obtained otherwise. [FETCH]

5.4. Example

In this example XMLHttpRequest, combined with concepts defined in the sections before, and the HTML progress element are used together to display the process of fetching a resource.

<!DOCTYPE html>
<title>Waiting for Magical Unicorns</title>
<progress id=p></progress>
<script>
  var progressBar = document.getElementById("p"),
      client = new XMLHttpRequest()
  client.open("GET", "magical-unicorns")
  client.onprogress = function(pe) {
    if(pe.lengthComputable) {
      progressBar.max = pe.total
      progressBar.value = pe.loaded
    }
  }
  client.onloadend = function(pe) {
    progressBar.value = pe.loaded
  }
  client.send()
</script>

Fully working code would of course be more elaborate and deal with more scenarios, such as network errors or the end user terminating the request.

Acknowledgments

Thanks to Addison Phillips, Adrian Bateman, Ahmed Kamel, Alan Thomas, Alex Hopmann, Alex Vincent, Alexey Proskuryakov, Ali Alabbas, Andrea Marchesini, Asbjørn Ulsberg, Bertrand Guay-Paquet, Björn Höhrmann, Boris Zbarsky, Caitlin Potter, Cameron McCormack, 白丞祐 (Cheng-You Bai), Chris Marrin, Christophe Jolif, Charles McCathieNevile, Dan Winship, David Andersson, David Flanagan, David Håsäther, David Levin, Dean Jackson, Denis Sureau, Domenic Denicola, Dominik Röttsches, Doug Schepers, Douglas Livingstone, Elliott Sprehn, Elliotte Harold, Eric Lawrence, Eric Uhrhane, Erik Arvidsson, Erik Dahlström, Feras Moussa, Gideon Cohn, Glenn Adams, Gorm Haug Eriksen, Gregory Terzian, Håkon Wium Lie, Hallvord R. M. Steen, Henri Sivonen, Hiroshige Hayashizaki, Huub Schaeks, Ian Clelland, Ian Davis, Ian Hickson, Ivan Herman, Jake Archibald, Jared Jacobs, Jarred Nicholls, Jeff Walden, Jens Lindström, Jim Deegan, Jim Ley, Joe Farro, Jonas Sicking, Julian Reschke, 송정기 (Jungkee Song), 呂康豪 (Kang-Hao Lu), Karl Dubost, Keith Yeung, 田村健人 (Kent TAMURA), Lachlan Hunt, Maciej Stachowiak, Magnus Kristiansen, Manish Goregaokar, Marc Hadley, Marcos Caceres, Mark Baker, Mark Birbeck, Mark Nottingham, Mark S. Miller, Martin Hassman, Mike Pennisi, Mohamed Zergaoui, Ms2ger, Odin Hørthe Omdal, Olli Pettay, Pawel Glowacki, Peter Michaux, Philip Jägenstedt, Philip Taylor, Robin Berjon, Rune F. Halvorsen, Ruud Steltenpool, Ryo Onodera, Sam Sneddon, Sergiu Dumitriu, Shivakumar Jagalur Matt, Sigbjørn Finne, Simon Pieters, Stewart Brodie, Sunava Dutta, Takeshi Kurosawa, Takeshi Yoshino, Thomas Roessler, Thomas Wisniewski, Tom Magliery, Travis Leithead, triple-underscore, Yaron Tausky, Yehuda Katz, Youenn Fablet, and Zhenbin Xu for their contributions to this standard.

Special thanks to the Microsoft employees who first implemented the XMLHttpRequest interface, which was first widely deployed by the Windows Internet Explorer browser.

Special thanks to Ian Hickson for drafting an initial version of this specification in the HTML Standard (then Web Applications 1.0). [HTML]

Special thanks to the W3C SVG WG for drafting the original ProgressEvent class as part of the SVG Micro DOM.

This standard is written by Anne van Kesteren (Mozilla, annevk@annevk.nl).

Intellectual property rights

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). This work is licensed under a Creative Commons Attribution 4.0 International License.

This is the Living Standard. Those interested in the patent-review version should view the Living Standard Review Draft.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[DOM-PARSING]
Travis Leithead. DOM Parsing and Serialization. URL: https://w3c.github.io/DOM-Parsing/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/
[ENCODING]
Anne van Kesteren. Encoding Standard. Living Standard. URL: https://encoding.spec.whatwg.org/
[FEATURE-POLICY]
Ian Clelland. Permissions Policy. URL: https://w3c.github.io/webappsec-permissions-policy/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[FILEAPI]
Marijn Kruisselbrink; Arun Ranganathan. File API. URL: https://w3c.github.io/FileAPI/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing Standard. Living Standard. URL: https://mimesniff.spec.whatwg.org/
[STREAMS]
Adam Rice; Domenic Denicola; 吉野剛史 (Takeshi Yoshino). Streams Standard. Living Standard. URL: https://streams.spec.whatwg.org/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Boris Zbarsky. Web IDL. URL: https://heycam.github.io/webidl/
[XML]
Tim Bray; et al. Extensible Markup Language (XML) 1.0 (Fifth Edition). 26 November 2008. REC. URL: https://www.w3.org/TR/xml/
[XML-NAMES]
Tim Bray; et al. Namespaces in XML 1.0 (Third Edition). 8 December 2009. REC. URL: https://www.w3.org/TR/xml-names/

IDL Index

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequestEventTarget : EventTarget {
  // event handlers
  attribute EventHandler onloadstart;
  attribute EventHandler onprogress;
  attribute EventHandler onabort;
  attribute EventHandler onerror;
  attribute EventHandler onload;
  attribute EventHandler ontimeout;
  attribute EventHandler onloadend;
};

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequestUpload : XMLHttpRequestEventTarget {
};

enum XMLHttpRequestResponseType {
  "",
  "arraybuffer",
  "blob",
  "document",
  "json",
  "text"
};

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
  constructor();

  // event handler
  attribute EventHandler onreadystatechange;

  // states
  const unsigned short UNSENT = 0;
  const unsigned short OPENED = 1;
  const unsigned short HEADERS_RECEIVED = 2;
  const unsigned short LOADING = 3;
  const unsigned short DONE = 4;
  readonly attribute unsigned short readyState;

  // request
  undefined open(ByteString method, USVString url);
  undefined open(ByteString method, USVString url, boolean async, optional USVString? username = null, optional USVString? password = null);
  undefined setRequestHeader(ByteString name, ByteString value);
           attribute unsigned long timeout;
           attribute boolean withCredentials;
  [SameObject] readonly attribute XMLHttpRequestUpload upload;
  undefined send(optional (Document or XMLHttpRequestBodyInit)? body = null);
  undefined abort();

  // response
  readonly attribute USVString responseURL;
  readonly attribute unsigned short status;
  readonly attribute ByteString statusText;
  ByteString? getResponseHeader(ByteString name);
  ByteString getAllResponseHeaders();
  undefined overrideMimeType(DOMString mime);
           attribute XMLHttpRequestResponseType responseType;
  readonly attribute any response;
  readonly attribute USVString responseText;
  [Exposed=Window] readonly attribute Document? responseXML;
};

typedef (File or USVString) FormDataEntryValue;

[Exposed=(Window,Worker)]
interface FormData {
  constructor(optional HTMLFormElement form);

  undefined append(USVString name, USVString value);
  undefined append(USVString name, Blob blobValue, optional USVString filename);
  undefined delete(USVString name);
  FormDataEntryValue? get(USVString name);
  sequence<FormDataEntryValue> getAll(USVString name);
  boolean has(USVString name);
  undefined set(USVString name, USVString value);
  undefined set(USVString name, Blob blobValue, optional USVString filename);
  iterable<USVString, FormDataEntryValue>;
};

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface ProgressEvent : Event {
  constructor(DOMString type, optional ProgressEventInit eventInitDict = {});

  readonly attribute boolean lengthComputable;
  readonly attribute unsigned long long loaded;
  readonly attribute unsigned long long total;
};

dictionary ProgressEventInit : EventInit {
  boolean lengthComputable = false;
  unsigned long long loaded = 0;
  unsigned long long total = 0;
};