XMLHttpRequest

Living Standard — Last Updated 11 October 2012

This Version:
http://xhr.spec.whatwg.org/
Participate:
Send feedback to public-webapps@w3.org (archives) or file a bug (open bugs)
IRC: #whatwg on Freenode
Version History:
https://github.com/whatwg/xhr/commits
Editor:
Anne van Kesteren <annevk@annevk.nl>

Abstract

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

Table of Contents

  1. 1 Introduction
    1. 1.1 Specification history
  2. 2 Conformance
    1. 2.1 Extensibility
  3. 3 Terminology
  4. 4 Interface XMLHttpRequest
    1. 4.1 Base URL, origin, and referrer
    2. 4.2 Task sources
    3. 4.3 Constructors
    4. 4.4 Garbage collection
    5. 4.5 Event handlers
    6. 4.6 States
    7. 4.7 Request
      1. 4.7.1 The open() method
      2. 4.7.2 The setRequestHeader() method
      3. 4.7.3 The timeout attribute
      4. 4.7.4 The withCredentials attribute
      5. 4.7.5 The upload attribute
      6. 4.7.6 The send() method
      7. 4.7.7 Infrastructure for the send() method
      8. 4.7.8 The abort() method
    8. 4.8 Response
      1. 4.8.1 The status attribute
      2. 4.8.2 The statusText attribute
      3. 4.8.3 The getResponseHeader() method
      4. 4.8.4 The getAllResponseHeaders() method
      5. 4.8.5 Response entity body
      6. 4.8.6 The overrideMimeType() method
      7. 4.8.7 The responseType attribute
      8. 4.8.8 The response attribute
      9. 4.8.9 The responseText attribute
      10. 4.8.10 The responseXML attribute
    9. 4.9 Events summary
  5. 5 Interface FormData
    1. 5.1 Constructors
    2. 5.2 The append() method
  6. 6 Interface ProgressEvent
    1. 6.1 Firing events using the ProgressEvent interface for HTTP
    2. 6.2 Firing events using the ProgressEvent interface for other contexts
    3. 6.3 Suggested names for events using the ProgressEvent interface
    4. 6.4 Security Considerations
    5. 6.5 Example
  7. 7 data: URLs and HTTP
  8. References
  9. Acknowledgments

1 Introduction

This section is non-normative.

The XMLHttpRequest object is the ECMAScript HTTP API. [ECMASCRIPT]

The name of the object is XMLHttpRequest for compatibility with the Web, though each component of this name is potentially misleading. First, the object supports any text based format, including XML. Second, it can be used to make requests over both HTTP and HTTPS (some implementations support protocols in addition to HTTP and HTTPS, but that functionality is not covered by this specification). Finally, it supports "requests" in a broad sense of the term as it pertains to HTTP; namely all activity involved with HTTP requests or responses for the defined HTTP methods.

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.readyState == this.DONE) {
    if(this.status == 200 &&
       this.responseXML != null &&
       this.responseXML.getElementById('test').textContent) {
      // success!
      processData(this.responseXML.getElementById('test').textContent);
      return;
    }
    // something went wrong
    processData(null);
  }
}

var client = new XMLHttpRequest();
client.onreadystatechange = 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.onreadystatechange = function() {
    // in case of network errors this might not give reliable results
    if(this.readyState == this.DONE)
      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. (Long after Microsoft shipped an implementation.) 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.

Historical discussion can be found in the following mailing list archives:

2 Conformance

All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.

The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this specification are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]

2.1 Extensibility

User agents, Working Groups, and other interested parties are strongly encouraged to discuss new features with the WHATWG community.

3 Terminology

This specification heavily borrows terminology, from Cross-Origin Resource Sharing, DOM, DOM Parsing and Serialization, Encoding, File API, HTML, HTTP, Typed Array, Web IDL, and XML. [CORS] [DOM] [DOMPS] [ENCODING] [FILEAPI] [HTML] [HTTP] [TYPEDARRAY] [WEBIDL] [XML] [XMLNS]

The term user credentials for the purposes of this specification means cookies, HTTP authentication, and client-side SSL certificates. Specifically it does not refer to proxy authentication or the Origin header. [COOKIES]

4 Interface XMLHttpRequest

[NoInterfaceObject]
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;
};

interface XMLHttpRequestUpload : XMLHttpRequestEventTarget {

};

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

[Constructor]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
  // 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
  void open(ByteString method, DOMString url, optional boolean async = true, optional DOMString? user, optional DOMString? password);
  void setRequestHeader(ByteString header, ByteString value);
           attribute unsigned long timeout;
           attribute boolean withCredentials;
  readonly attribute XMLHttpRequestUpload upload;
  void send(optional (ArrayBufferView or Blob or Document or DOMString or FormData)? data = null);
  void abort();

  // response
  readonly attribute unsigned short status;
  readonly attribute ByteString statusText;
  ByteString? getResponseHeader(ByteString header);
  ByteString getAllResponseHeaders();
  void overrideMimeType(DOMString mime);
           attribute XMLHttpRequestResponseType responseType;
  readonly attribute any response;
  readonly attribute DOMString responseText;
  readonly attribute Document? responseXML;
};

[Constructor]
interface AnonXMLHttpRequest : XMLHttpRequest {
};

4.1 Base URL, origin, and referrer

Each XMLHttpRequest object has an associated XMLHttpRequest base URL, XMLHttpRequest origin, and XMLHttpRequest referrer source.

The XMLHttpRequest standard defines XMLHttpRequest base URL, XMLHttpRequest origin, and XMLHttpRequest referrer source when the global object is represented by the Window object. Other contexts will have to define them as appropriate for XMLHttpRequest to function as other contexts are considered out of scope for this document.

In environments where the global object is represented by the Window object the XMLHttpRequest object has an associated XMLHttpRequest document which is the document associated with the Window object for which the XMLHttpRequest interface object was created.

In these environments the XMLHttpRequest referrer source is that XMLHttpRequest document.

The XMLHttpRequest document is also used to determine the XMLHttpRequest base URL and XMLHttpRequest origin at a later stage.

4.2 Task sources

Each XMLHttpRequest object has its own task source. Namely, the XMLHttpRequest task source.

4.3 Constructors

The XMLHttpRequest object has an associated anonymous flag. If the anonymous flag is set, user credentials and the XMLHttpRequest origin are not exposed when fetching resources. It can only be set to true by using the AnonXMLHttpRequest() constructor.

We might remove the AnonXMLHttpRequest() constructor.

client = new XMLHttpRequest()
Returns a new XMLHttpRequest object.
client = new AnonXMLHttpRequest()
Returns a new AnonXMLHttpRequest object that has the anonymous flag set.

The XMLHttpRequest() constructor must return a new XMLHttpRequest object.

The AnonXMLHttpRequest() constructor must return a new AnonXMLHttpRequest object with its anonymous flag set.

4.4 Garbage collection

An XMLHttpRequest object must not be garbage collected if its state is OPENED and the send() flag is set, its state is HEADERS_RECEIVED, or its state is LOADING, and one of the following is true:

If an XMLHttpRequest object is garbage collected while its connection is still open, the user agent must cancel any instance of the fetch algorithm opened by this object, discarding any tasks queued for them, and discarding any further data received from the network for them.

4.5 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
onloadstart loadstart
onprogress progress
onabort abort
onerror error
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
onreadystatechange readystatechange

4.6 States

client . readyState

Returns the current state.

The XMLHttpRequest object can be in several states. The readyState attribute must return the current state, which must be one of the following values:

UNSENT (numeric value 0)

The object has been constructed.

OPENED (numeric value 1)

The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the request can be made using the send() method.

HEADERS_RECEIVED (numeric value 2)

All redirects (if any) have been followed and all HTTP headers of the final response have been received. Several response members of the object are now available.

LOADING (numeric value 3)

The response entity body is being received.

DONE (numeric value 4)

The data transfer has been completed or something went wrong during the transfer (e.g. infinite redirects).

The send() flag indicates that the send() method has been invoked. It is initially unset and is used during the OPENED state.

The error flag indicates some type of network error or request abortion. It is initially unset and is used during the DONE state.

4.7 Request

Each XMLHttpRequest object has the following request-associated concepts:

synchronous flag
Set when fetching is done synchronously. Initially unset.
request method
The HTTP method used in the request.
request URL
The resolved URL used in the request.
request username
The username used in the request or null if there is no username.
request password
The password used in the request or null if there is no password.
author request headers
A list consisting of HTTP header name/value pairs to be used in the request.
request entity body
The entity body used in the request or null if there is no entity body.
upload complete flag
Set when no more events are to be dispatched on the XMLHttpRequestUpload object. Initially unset.
upload events flag
Set when event listeners are registered on the XMLHttpRequestUpload object to determine whether a preflight request is needed. Initially unset.

Each XMLHttpRequest object also has a unique, associated XMLHttpRequestUpload object.

4.7.1 The open() method

client . open(method, url, async, user, password)

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

Throws a "SyntaxError" exception if one of the following is true:

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

Throws an "InvalidAccessError" exception if one of the following is true:

The open(method, url, async, user, password) method must run these steps (unless otherwise indicated):

  1. If there is an associated XMLHttpRequest document run these substeps:

    1. If the XMLHttpRequest document is not fully active, throw an "InvalidStateError" exception and terminate the overall set of steps.

    2. Let XMLHttpRequest base URL be the document base URL of the XMLHttpRequest document.

    3. Let XMLHttpRequest origin be the origin of the XMLHttpRequest document and let it be a globally unique identifier if the anonymous flag is set.

  2. If method does not match the Method token production, throw a "SyntaxError" exception and terminate these steps.

  3. If method is a case-insensitive match for CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, TRACE, or TRACK subtract 0x20 from each byte in the range 0x61 (ASCII a) to 0x7A (ASCII z).

    If it does not match any of the above, it is passed through literally, including in the final request.

  4. If method is a case-sensitive match for CONNECT, TRACE, or TRACK, throw a "SecurityError" exception and terminate these steps.

    Allowing these methods would pose a security risk. [HTTPVERBSEC]

  5. Let url be a URL with character encoding UTF-8.

  6. Resolve url relative to the XMLHttpRequest base URL. If the algorithm returns an error, throw a "SyntaxError" exception and terminate these steps.

  7. Drop <fragment> from url.

  8. If the "user:password" format in the userinfo production is not supported for the relevant <scheme> and url contains this format, throw a "SyntaxError" and terminate these steps.

  9. If url contains the "user:password" format let temp user be the user part and temp password be the password part.

  10. If url just contains the "user" format let temp user be the user part.

  11. If async is false, there is an associated XMLHttpRequest document and either the timeout attribute value is not zero, the withCredentials attribute value is true, or the responseType attribute value is not the empty string, throw an "InvalidAccessError" exception and terminate these steps.

  12. If the user argument was not omitted follow these substeps:

    1. If user is not null and the origin of url is not same origin with the XMLHttpRequest origin, throw an "InvalidAccessError" exception and terminate the overall set of steps.

    2. Let temp user be user.

    These steps override anything that may have been set by the url argument.

  13. If the password argument was not omitted follow these substeps:

    1. If password is not null and the origin of url is not same origin with the XMLHttpRequest origin, throw an "InvalidAccessError" exception and terminate the overall set of steps.

    2. Let temp password be password.

    These steps override anything that may have been set by the url argument.

  14. Terminate the abort() algorithm.

  15. Terminate the send() algorithm.

  16. The user agent should cancel any network activity for which the object is responsible.

  17. If there are any tasks from the object's XMLHttpRequest task source in one of the task queues, then remove them.

  18. Set variables associated with the object as follows:

  19. Change the state to OPENED.

  20. Fire an event named readystatechange.

4.7.2 The setRequestHeader() method

client . setRequestHeader(header, value)

Appends an header to the list of author request headers, or if header is already in the list of author request headers, combines its value with value.

Throws an "InvalidStateError" exception if the state is not OPENED or if the send() flag is set.

Throws a "SyntaxError" exception if header is not a valid HTTP header field name or if value is not a valid HTTP header field value.

As indicated in the algorithm below certain headers cannot be set and are left up to the user agent. In addition there are certain other headers the user agent will take control of if they are not set by the author as indicated at the end of the send() method section.

For non same origin requests using the HTTP GET method a preflight request is made when headers other than Accept and Accept-Language are set.

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

  1. If the state is not OPENED, throw an "InvalidStateError" exception and terminate these steps.

  2. If the send() flag is set, throw an "InvalidStateError" exception and terminate these steps.

  3. If header does not match the field-name production, throw a "SyntaxError" exception and terminate these steps.

  4. If value does not match the field-value production, throw a "SyntaxError" exception and terminate these steps.

    The empty string is legal and represents the empty header value.

  5. Terminate these steps if header is a case-insensitive match for one of the following headers:

    … or if the start of header is a case-insensitive match for Proxy- or Sec- (including when header is just Proxy- or Sec-).

    The above headers are controlled by the user agent to let it control those aspects of transport. This guarantees data integrity to some extent. Header names starting with Sec- are not allowed to be set to allow new headers to be minted that are guaranteed not to come from XMLHttpRequest.

  6. If header is not in the author request headers list, append header with its associated value to the list and terminate these steps.

  7. If header is in the author request headers list, combine value with the value of the header matching header in the author request headers list (for combine see section 4.2, RFC 2616). [HTTP]

    The XMLHttpRequest standard intentionally constraints the use of HTTP here in line with contemporary implementations.

See also the send() method regarding user agent header handling for caching, authentication, proxies, and cookies.

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

4.7.3 The timeout attribute

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, if the synchronous flag is unset, a timeout event will then be dispatched, or a "TimeoutError" exception will be thrown otherwise (for the send() method).

When set: throws an "InvalidAccessError" exception if the synchronous flag is set when there is an associated XMLHttpRequest document.

The timeout attribute must return its value. Initially its value must be zero.

Setting the timeout attribute must run these steps:

  1. If there is an associated XMLHttpRequest document and the synchronous flag is set, throw an "InvalidAccessError" exception and terminate these steps.

  2. Set its value to the new 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.

4.7.4 The withCredentials attribute

client . withCredentials

True when user 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" exception if the state is not UNSENT or OPENED, or if the send() flag is set.

When set: throws an "InvalidAccessError" exception if either the synchronous flag is set when there is an associated XMLHttpRequest document or if the anonymous flag is set.

The withCredentials attribute must return its value. Initially its value must be false.

Setting the withCredentials attribute must run these steps:

  1. If the state is not UNSENT or OPENED, throw an "InvalidStateError" exception and terminate these steps.

  2. If the send() flag is set, throw an "InvalidStateError" exception and terminate these steps.

  3. If the anonymous flag is set, throw an "InvalidAccessError" exception and terminate these steps.

  4. If there is an associated XMLHttpRequest document and the synchronous flag is set, throw an "InvalidAccessError" exception and terminate these steps.

  5. Set the withCredentials attribute's value to the given value.

The withCredentials attribute has no effect when fetching same-origin resources.

4.7.5 The upload attribute

client . upload

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

The upload attribute must return the associated XMLHttpRequestUpload object.

As indicated earlier, each XMLHttpRequest object has an associated XMLHttpRequestUpload object.

4.7.6 The send() method

client . send(data)

Initiates the request. The optional argument provides the request entity body. The argument is ignored if request method is GET or HEAD.

Throws an "InvalidStateError" exception if the state is not OPENED or if the send() flag is set.

The send(data) method must run these steps (unless otherwise noted). This algorithm can be terminated by invoking the open() or abort() method. When it is terminated the user agent must terminate the algorithm after finishing the step it is on.

The send() algorithm can only be terminated if the synchronous flag is unset and only after the method call has returned.

  1. If the state is not OPENED, throw an "InvalidStateError" exception and terminate these steps.

  2. If the send() flag is set, throw an "InvalidStateError" exception and terminate these steps.

  3. If the request method is GET or HEAD, set data to null.

  4. If data is null, do not include a request entity body and go to the next step.

    Otherwise, let encoding be null, mime type be null, and then follow these rules, depending on data:

    ArrayBufferView

    Let the request entity body be the raw data represented by data.

    Blob

    If the object's type attribute is not the empty string let mime type be its value.

    Let the request entity body be the raw data represented by data.

    document

    Let encoding be the encoding of data. If encoding is utf-16 or utf-16be, set encoding to utf-8.

    If data is an HTML document, let mime type be "text/html", or let mime type be "application/xml" otherwise. Then append ";charset=encoding" to mime type.

    Serialize data, and let the request entity body be the result, converted to Unicode and encoded using encoding encoding. Re-throw any exception this throws.

    Should we only encode as utf-8? What happens in the face of an encoder error?

    In particular, if the document cannot be serialized an "InvalidStateError" exception is thrown.

    Subsequent changes to the document have no effect on what is transferred.

    a string

    Let encoding be UTF-8.

    Let mime type be "text/plain;charset=UTF-8".

    Let the request entity body be data converted to Unicode and encoded as utf-8.

    FormData

    Let the request entity body be the result of running the multipart/form-data encoding algorithm with data as form data set and with UTF-8 as the explicit character encoding.

    Let mime type be the concatenation of "multipart/form-data;", a U+0020 SPACE character, "boundary=", and the multipart/form-data boundary string generated by the multipart/form-data encoding algorithm.

    If a Content-Type header is in author request headers and its value is a valid MIME type that has a charset parameter whose value is not a case-insensitive match for encoding, and encoding is not null, set all the charset parameters of that Content-Type header to encoding.

    If no Content-Type header is in author request headers and mime type is not null, append a Content-Type header with value mime type to author request headers.

  5. If the synchronous flag is set, release the storage mutex.

  6. If the synchronous flag is unset and one or more event listeners are registered on the XMLHttpRequestUpload object, set the upload events flag.

  7. Unset the error flag.

  8. Set the upload complete flag if there is no request entity body or if the request entity body is empty.

  9. If the synchronous flag is unset, run these substeps:

    1. Set the send() flag.

    2. Fire a progress event named loadstart.

    3. If the upload complete flag is unset, fire a progress event named loadstart on the XMLHttpRequestUpload object.

    4. Return the send() method call, but continue running the steps in this algorithm.

  10. If the XMLHttpRequest origin and the request URL are same origin
    If the request URL's <scheme> is "data"

    These are the same-origin request steps.

    Fetch the request URL from origin XMLHttpRequest origin, using XMLHttpRequest referrer source as override referrer source, with the synchronous flag set if the synchronous flag is set, using HTTP method request method, user request username (if non-null) and password request password (if non-null), taking into account the request entity body, list of author request headers and the rules listed at the end of this section.

    If the synchronous flag is set

    While making the request also follow the same-origin request event rules.

    The send() method call will now be returned by virtue of this algorithm ending.

    If the synchronous flag is unset

    Make upload progress notifications.

    Make progress notifications.

    While processing the request, as data becomes available and when the user interferes with the request, queue tasks to update the response entity body and follow the same-origin request event rules.

    Otherwise

    These are the cross-origin request steps.

    Make a cross-origin request, passing these as parameters:

    request URL
    The request URL.
    request method
    The request method.
    author request headers
    The list of author request headers.
    request entity body
    The request entity body.
    source origin
    The XMLHttpRequest origin.
    referrer source
    If the anonymous flag is set the URL "about:blank", or the XMLHttpRequest referrer source otherwise.
    omit credentials flag
    Set if withCredentials attribute's value is false.
    force preflight flag
    Set if the upload events flag is set.

    Request username and request password are always ignored as part of a cross-origin request; including them would allow a site to perform a distributed password search. However, user agents will include user credentials in the request (if the user has any and if withCredentials is true).

    If the synchronous flag is set

    While making the request also follow the cross-origin request event rules.

    The send() method call will now be returned by virtue of this algorithm ending.

    If the synchronous flag is unset

    While processing the request, as data becomes available and when the end user interferes with the request, queue tasks to update the response entity body and follow the cross-origin request event rules.


If the user agent allows the end user to configure a proxy it should modify the request appropriately; i.e., connect to the proxy host instead of the origin server, modify the Request-Line and send Proxy-Authorization headers as specified.


If the user agent supports HTTP Authentication and Authorization is not in the list of author request headers, it should consider requests originating from the XMLHttpRequest object to be part of the protection space that includes the accessed URIs and send Authorization headers and handle 401 Unauthorized requests appropriately.

If authentication fails, XMLHttpRequest origin and the request URL are same origin, Authorization is not in the list of author request headers, request username is null, and request password is null, user agents should prompt the end user for their username and password.

Otherwise, if authentication fails, user agents must not prompt the end user for their username and password. [HTTPAUTH]

End users are not prompted for various cases so that authors can implement their own user interface.


If the user agent supports HTTP State Management it should persist, discard and send cookies (as received in the Set-Cookie response header, and sent in the Cookie header) as applicable. [COOKIES]


If the user agent implements a HTTP cache it should respect Cache-Control headers in author request headers (e.g. Cache-Control: no-cache bypasses the cache). It must not send Cache-Control or Pragma request headers automatically unless the end user explicitly requests such behavior (e.g. by reloading the page).

For 304 Not Modified responses that are a result of a user agent generated conditional request the user agent must act as if the server gave a 200 OK response with the appropriate content. The user agent must allow author request headers to override automatic cache validation (e.g. If-None-Match or If-Modified-Since), in which case 304 Not Modified responses must be passed through. [HTTP]


If the user agent implements server-driven content-negotiation it must follow these constraints for the Accept and Accept-Language request headers:

Responses must have the content-encodings automatically decoded. [HTTP]


Besides the author request headers, user agents should not include additional request headers other than those mentioned above or other than those authors are not allowed to set using setRequestHeader(). This ensures that authors have a predictable API.

4.7.7 Infrastructure for the send() method

The same-origin request event rules are as follows:

If the response has an HTTP status code of 301, 302, 303, 307, or 308

If the redirect violates infinite loop precautions this is a network error.

Otherwise, run these steps:

  1. Set the request URL to the URL conveyed by the Location header.

  2. If the XMLHttpRequest origin and the origin of request URL are same origin transparently follow the redirect while observing the same-origin request event rules.

  3. Otherwise, follow the cross-origin request steps and terminate the steps for this algorithm.

HTTP places requirements on the user agent regarding the preservation of the request method and request entity body during redirects, and also requires end users to be notified of certain kinds of automatic redirections.

If the end user cancels the request

This is an abort error.

If there is a network error

In case of DNS errors, TLS negotiation failure, or other type of network errors, this is a network error. Do not request any kind of end user interaction.

This does not include HTTP responses that indicate some type of error, such as HTTP status code 410.

If timeout is not 0 and since the request started the amount of milliseconds specified by timeout has passed

This is a timeout error.

Once all HTTP headers have been received, the synchronous flag is unset, and the HTTP status code of the response is not one of 301, 302, 303, 307, and 308

Switch to the HEADERS_RECEIVED state.

Once the first byte (or more) of the response entity body has been received and the synchronous flag is unset
If there is no response entity body and the synchronous flag is unset

Switch to the LOADING state.

Once the whole response entity body has been received
If there is no response entity body and the state is LOADING
If there is no response entity body and the synchronous flag is set

Switch to the DONE state.


The cross-origin request event rules are as follows:

If the cross-origin request status is preflight complete and the synchronous flag is unset

Make upload progress notifications.

If the cross-origin request status is network error

This is a network error.

If the cross-origin request status is abort error

This is an abort error.

If timeout is not 0 and since the request started the amount of milliseconds specified by timeout has passed

This is a timeout error.

Once all HTTP headers have been received, the cross-origin request status is success, and the synchronous flag is unset

Switch to the HEADERS_RECEIVED state.

Make progress notifications.

Once the first byte (or more) of the response entity body has been received, the cross-origin request status is success, and the synchronous flag is unset
If there is no response entity body, the cross-origin request status is success, and the synchronous flag is unset

Switch to the LOADING state.

Once the whole response entity body has been received and the cross-origin request status is success
If there is no response entity body, the cross-origin request status is success, and the state is LOADING
If there is no response entity body, the cross-origin request status is success, and the synchronous flag is set

Switch to the DONE state.


When something is said to be a network error run the request error steps for exception "NetworkError" and event error.

When something is said to be an abort error run the request error steps for exception "AbortError" and event abort.

When something is said to be an timeout error run the request error steps for exception "TimeoutError" and event timeout.

When something is said to be a request error for exception exception and event event run these steps:

  1. The user agent should cancel any network activity for which the object is responsible.

  2. If there are any tasks from the object's XMLHttpRequest task source in one of the task queues, then remove them.

  3. Set the the error flag.

  4. Change the state to DONE.

  5. If the synchronous flag is set, throw an exception exception and terminate the overall set of steps.

  6. Fire an event named readystatechange.

    At this point it is clear that the synchronous flag is unset.

  7. If the upload complete flag is unset, follow these substeps:

    1. Set the upload complete flag.

    2. Fire a progress event named progress on the XMLHttpRequestUpload object.

    3. Fire a progress event named event on the XMLHttpRequestUpload object.

    4. Fire a progress event named loadend on the XMLHttpRequestUpload object.

  8. Fire a progress event named progress.

  9. Fire a progress event named event.

  10. Fire a progress event named loadend.


When it is said to switch to the HEADERS_RECEIVED state run these steps:

  1. Change the state to HEADERS_RECEIVED.

  2. Fire an event named readystatechange.

When it is said to switch to the LOADING state run these steps:

  1. Change the state to LOADING.

  2. Fire an event named readystatechange.

When it is said to switch to the DONE state run these steps:

  1. If the synchronous flag is set, update the response entity body.

  2. Unset the synchronous flag.

  3. Change the state to DONE.

  4. Fire an event named readystatechange.

  5. Fire a progress event named progress.

  6. Fire a progress event named load.

  7. Fire a progress event named loadend.


When it is said to make progress notifications, while the download is progressing, queue a task to fire a progress event named progress about every 50ms or for every byte received, whichever is least frequent.


When it is said to make upload progress notifications run these steps:

4.7.8 The abort() method

client . abort()
Cancels any network activity.

The abort() method must run these steps (unless otherwise noted). This algorithm can be terminated by invoking the open() method. When it is terminated the user agent must terminate the algorithm after finishing the step it is on.

The abort() algorithm can only be terminated by invoking open() from an event handler.

  1. Terminate the send() algorithm.

  2. The user agent should cancel any network activity for which the object is responsible.

  3. If there are any tasks from the object's XMLHttpRequest task source in one of the task queues, then remove them.

  4. Set the error flag.

  5. Unset the synchronous flag.

  6. If the state is UNSENT, OPENED with the send() flag being unset, or DONE go to the next step.

    Otherwise run these substeps:

    1. Change the state to DONE.

    2. Unset the send() flag.

    3. Fire an event named readystatechange.

    4. Fire a progress event named progress.

    5. Fire a progress event named abort.

    6. Fire a progress event named loadend.

    7. If the upload complete flag is false run these substeps:

      1. Set the upload complete flag to true.

      2. Fire a progress event named progress on the XMLHttpRequestUpload object.

      3. Fire a progress event named abort on the XMLHttpRequestUpload object.

      4. Fire a progress event named loadend on the XMLHttpRequestUpload object.

  7. Change the state to UNSENT.

    No readystatechange event is dispatched.

4.8 Response

4.8.1 The status attribute

client . status

Returns the HTTP status code.

The status attribute must return the result of running these steps:

  1. If the state is UNSENT or OPENED, return 0 and terminate these steps.

  2. If the error flag is set, return 0 and terminate these steps.

  3. Return the HTTP status code.

4.8.2 The statusText attribute

client . statusText

Returns the HTTP status text.

The statusText attribute must return the result of running these steps:

  1. If the state is UNSENT or OPENED, return the empty string and terminate these steps.

  2. If the error flag is set, return the empty string and terminate these steps.

  3. Return the HTTP status text.

4.8.3 The getResponseHeader() method

client . getResponseHeader(header)

Returns the header field value from the response of which the field name matches header, unless the field name is Set-Cookie or Set-Cookie2.

The getResponseHeader(header) method must run these steps:

  1. If the state is UNSENT or OPENED, return null and terminate these steps.

  2. If the error flag is set, return null and terminate these steps.

  3. If header is a case-insensitive match for Set-Cookie or Set-Cookie2, return null and terminate these steps.

  4. If header is a case-insensitive match for multiple HTTP response headers, return the values of these headers as a single concatenated string separated from each other by a U+002C COMMA U+0020 SPACE character pair and terminate these steps.

  5. If header is a case-insensitive match for a single HTTP response header, return the value of that header and terminate these steps.

  6. Return null.

The Cross-Origin Resource Sharing specification filters the headers that are exposed by getResponseHeader() for non same-origin requests. [CORS]

For the following script:

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

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

text/plain; charset=UTF-8

4.8.4 The getAllResponseHeaders() method

client . getAllResponseHeaders()

Returns all headers from the response, with the exception of those whose field name is Set-Cookie or Set-Cookie2.

The getAllResponseHeaders() method must run these steps:

  1. If the state is UNSENT or OPENED, return the empty string and terminate these steps.

  2. If the error flag is set, return the empty string and terminate these steps.

  3. Return all the HTTP headers, excluding headers that are a case-insensitive match for Set-Cookie or Set-Cookie2, as a single string, with each header line separated by a U+000D CR U+000A LF pair, excluding the status line, and with each header name and header value separated by a U+003A COLON U+0020 SPACE pair.

The Cross-Origin Resource Sharing specification filters the headers that are exposed by getAllResponseHeaders() for non same-origin requests. [CORS]

For the following script:

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

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

Date: Sun, 24 Oct 2004 04:58:38 GMT
Server: Apache/1.3.31 (Unix)
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/plain; charset=utf-8

4.8.5 Response entity body

The response MIME type is the MIME type the Content-Type header contains excluding any parameters and converted to ASCII lowercase, or null if the response header can not be parsed or was omitted. The override MIME type is initially null and can get a value if overrideMimeType() is invoked. Final MIME type is the override MIME type unless that is null in which case it is the response MIME type.

The response charset is the value of the charset parameter of the Content-Type header or null if there was no charset parameter or the header could not be parsed or was omitted. The override charset is initially null and can get a value if overrideMimeType() is invoked. Final charset is the override charset unless that is null in which case it is the response charset.


The response entity body is the fragment of the entity body of the response received so far (LOADING) or the complete entity body of the response (DONE). If the response does not have an entity body, the response entity body is null.

The response entity body is updated as part of the send() algorithm.


The arraybuffer response entity body is an ArrayBuffer representing the response entity body. If the arraybuffer response entity body has no value assigned to it let it be the return value of the following algorithm:

  1. If the response entity body is null, return an empty ArrayBuffer object and terminate these steps.

  2. Return an ArrayBuffer object representing the response entity body.

The blob response entity body is a Blob representing the response entity body. If the blob response entity body has no value assigned to it let it be the return value of the following algorithm:

  1. If the response entity body is null, return an empty Blob object and terminate these steps.

  2. Return a Blob object representing the response entity body.

The document response entity body is either a document representing the response entity body or null. If the document response entity body has no value assigned to it let it be the return value of the following algorithm:

  1. If the response entity body is null, return null and terminate these steps.

  2. If final MIME type is not null, text/html, text/xml, application/xml, or does not end in +xml, return null and terminate these steps.

  3. If responseType is the empty string and final MIME type is text/html, return null and terminate these steps.

    This is restricted to responseType being "document" in order to prevent breaking legacy content.

  4. If final MIME type is text/html, run these substeps:

    1. Let charset be the final charset.

    2. If charset is null, prescan the first 1024 bytes of the response entity body and if that does not terminate unsuccessfully then let charset be the return value.

    3. If charset is null, set charset to utf-8.

    4. Decode byte stream response entity body using fallback encoding charset and then let document be a document that represents the result of that, parsed following the rules set forth in the HTML specification for an HTML parser with scripting disabled. [HTML]

    5. Set document's encoding to charset.

  5. Otherwise, let document be a document that represents the result of parsing the response entity body following the rules set forth in the XML specifications. If that fails (unsupported character encoding, namespace well-formedness error, etc.), return null and terminate these steps. [XML] [XMLNS]

    Scripts in the resulting document tree will not be executed, resources referenced will not be loaded and no associated XSLT will be applied.

  6. Set document's origin to the XMLHttpRequest origin.

  7. Set document's content type to final MIME type.

  8. Set document's URL to request URL.

  9. Return document.

The JSON response entity body is an ECMAScript value representing the response entity body. The JSON response entity body is the return value of the following algorithm:

  1. Let JSON text be the result of running utf-8 decode on byte stream response entity body.

  2. Return the result of invoking the parse function of the JSON object defined in ECMAScript, with JSON text as its only argument, or null if that function throws an exception. [ECMASCRIPT]

The text response entity body is a string representing the response entity body. The text response entity body is the return value of the following algorithm:

  1. If the response entity body is null, return the empty string and terminate these steps.

  2. Let charset be the final charset.

  3. If responseType is the empty string, charset is null, and final MIME type is either null, text/xml, application/xml or ends in +xml, use the rules set forth in the XML specifications to determine the encoding. Let charset be the determined encoding. [XML] [XMLNS]

    This is restricted to responseType being the empty string to keep the non-legacy responseType value "text" simple.

  4. If charset is null, set charset to utf-8.

  5. Return the result of running decode on byte stream response entity body using fallback encoding charset.

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

4.8.6 The overrideMimeType() method

client . overrideMimeType(mime)

Sets the Content-Type header for the response to mime.

Throws an "InvalidStateError" exception if the state is LOADING or DONE.

Throws a "SyntaxError" exception if mime is not a valid media type.

The overrideMimeType(mime) method must run these steps:

  1. If the state is LOADING or DONE, throw an "InvalidStateError" exception and terminate these steps.

  2. If parsing mime analogously to the value of the Content-Type headers fails, throw a "SyntaxError" exception and terminate these steps.

  3. If a MIME type is successfully parsed, set override MIME type to that MIME type, excluding any parameters, and converted to ASCII lowercase.

  4. If a charset parameter is successfully parsed, set override charset to its value.

4.8.7 The responseType attribute

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: throws an "InvalidStateError" exception if the state is LOADING or DONE.

When set: throws an "InvalidAccessError" exception if the synchronous flag is set and there is an associated XMLHttpRequest document.

The responseType attribute must return its value. Initially its value must be the empty string.

Setting the responseType attribute must run these steps:

  1. If the state is LOADING or DONE, throw an "InvalidStateError" exception and terminate these steps.

  2. If there is an associated XMLHttpRequest document and the synchronous flag is set, throw an "InvalidAccessError" exception and terminate these steps.

  3. Set the responseType attribute's value to the given value.

4.8.8 The response attribute

client . response

Returns the response entity body.

The response attribute must return the result of running these steps:

If responseType is the empty string or "text"
  1. If the state is not LOADING or DONE, return the empty string and terminate these steps.

  2. If the error flag is set, return the empty string and terminate these steps.

  3. Return the text response entity body.

Otherwise
  1. If the state is not DONE, return null and terminate these steps.

  2. If the error flag is set, return null and terminate these steps.

  3. If responseType is "arraybuffer"

    Return the arraybuffer response entity body.

    If responseType is "blob"

    Return the blob response entity body.

    If responseType is "document"

    Return the document response entity body.

    If responseType is "json"

    Return the JSON response entity body.

4.8.9 The responseText attribute

client . responseText

Returns the text response entity body.

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

The responseText attribute must return the result of running these steps:

  1. If responseType is not the empty string or "text", throw an "InvalidStateError" exception and terminate these steps.

  2. If the state is not LOADING or DONE, return the empty string and terminate these steps.

  3. If the error flag is set, return the empty string and terminate these steps.

  4. Return the text response entity body.

4.8.10 The responseXML attribute

client . responseXML

Returns the document response entity body.

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

The responseXML attribute must return the result of running these steps:

  1. If responseType is not the empty string or "document", throw an "InvalidStateError" exception and terminate these steps.

  2. If the state is not DONE, return null and terminate these steps.

  3. If the error flag is set, return null and terminate these steps.

  4. Return the document response entity body.

The responseXML attribute has XML in its name for historical reasons. It also returns HTML resources as documents.

4.9 Events summary

This section is non-normative.

The following events are dispatched on XMLHttpRequest and/or XMLHttpRequestUpload objects:

Event name Interface Dispatched when…
readystatechange Event The readyState attribute changes at some seemingly arbitrary times for historical reasons.
loadstart ProgressEvent When the request starts.
progress ProgressEvent While sending and loading data.
abort ProgressEvent When the request has been aborted. For instance, by invoking the abort() method.
error ProgressEvent When the request has failed.
load ProgressEvent When the request has successfully completed.
timeout ProgressEvent When the author specified timeout has passed before the request could complete.
loadend ProgressEvent When the request has completed (either in success or failure).

5 Interface FormData

The FormData object represents an ordered collection of entries. Each entry has a name, a value, a type, and optionally a filename (if type is "file").

[Constructor,
 Constructor(HTMLFormElement form)]
interface FormData {
  void append(DOMString name, Blob value, optional DOMString filename);
  void append(DOMString name, DOMString value);
};

5.1 Constructors

fd = new FormData()

Returns a new FormData object.

The FormData() constructor must return a new FormData object.

The FormData(form) constructor must return a new FormData object with as entries the result of constructing the form data set for form.

5.2 The append() method

fd . append(name, value [, filename])

Appends a new name/value-pair to the FormData object, optionally with a filename.

The append(name, value, filename) method must create a new entry with the following parameters set and append it to the end of the collection the FormData object represents:

6 Interface ProgressEvent

[Constructor(DOMString type, optional ProgressEventInit eventInitDict)]
interface ProgressEvent : Event {
  readonly attribute boolean lengthComputable;
  readonly attribute unsigned long long loaded;
  readonly attribute unsigned long long total;
};

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

Events using the ProgressEvent interface indicate some kind of progression.

The lengthComputable attribute must return the value it was initialized to. When an event is created the attribute must be initialized to false.

The loaded and total attributes must return the value they were initialized to. When an event is created the attributes must be initialized to 0.

6.1 Firing events using the ProgressEvent interface for HTTP

To fire a progress event named e means to fire an event named e with an event using the ProgressEvent interface that also meets these conditions:

6.2 Firing events using the ProgressEvent interface for other contexts

This is left as an exercise for the editor of the specification that introduces such a context. The editor is encouraged to define it in a way consistent with this and other specifications that utilize events using the ProgressEvent interface.

6.3 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. Zero or more. After loadstart has been dispatched.
error Progression failed. Zero or once. After the last progress has been dispatched, or after loadstart has been dispatched if progress has not been dispatched.
abort Progression is terminated. Zero or once.
load Progression is successful. Zero or once.
loadend Progress has stopped. Once. After one of error, abort, or load has been dispatched.

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

Throughout the web platform the error, abort, 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.

6.4 Security Considerations

For cross-origin requests some kind of opt-in, e.g. Cross-Origin Resource Sharing, 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. [CORS]

6.5 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.

7 data: URLs and HTTP

To ensure data: URLs can function in APIs designed around HTTP, such as XMLHttpRequest, this section details how they work. Specifications defining similar URL schemes ought to take inspiration from this section.

When a data: URL is fetched using the HTTP method GET, determine the response as follows:

When a data: URL is fetched using the HTTP method that is not GET, determine the response as follows:

References

[COOKIES]
HTTP State Management Mechanism, Adam Barth. IETF.
[CORS]
Cross-Origin Resource Sharing, Anne van Kesteren. WHATWG.
[DOM]
DOM, Anne van Kesteren, Aryeh Gregor and Ms2ger. WHATWG.
[DOMPS]
DOM Parsing and Serialization, Ms2ger. WHATWG.
[ECMASCRIPT]
ECMAScript Language Specification. ECMA.
[ENCODING]
Encoding Standard, Anne van Kesteren. WHATWG.
[FILEAPI]
File API, Arun Ranganathan and Jonas Sicking. W3C.
[HTML]
HTML, Ian Hickson. WHATWG.
[HTTP]
Hypertext Transfer Protocol -- HTTP/1.1, Roy Fielding, James Gettys, Jeffrey Mogul et al.. IETF.
[HTTPAUTH]
HTTP Authentication: Basic and Digest Access Authentication, J. Franks, Phillip Hallam-Baker, J. Hostetler et al.. IETF.
[HTTPVERBSEC]
Multiple vendors' web servers enable HTTP TRACE method by default. US-CERT.
Microsoft Internet Information Server (IIS) vulnerable to cross-site scripting via HTTP TRACK method. US-CERT.
HTTP proxy default configurations allow arbitrary TCP connections. US-CERT.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, Scott Bradner. IETF.
[TYPEDARRAY]
Typed Array, David Herman and Kenneth Russell. Khronos.
[WEBIDL]
Web IDL, Cameron McCormack. W3C.
[XML]
Extensible Markup Language, Tim Bray, Jean Paoli, C. M. Sperberg-McQueen et al.. W3C.
[XMLNS]
Namespaces in XML, Tim Bray, Dave Hollander, Andrew Layman et al.. W3C.

Acknowledgments

The editor would like to thank Addison Phillips, Ahmed Kamel, Alex Hopmann, Alex Vincent, Alexey Proskuryakov, Asbjørn Ulsberg, Boris Zbarsky, Björn Höhrmann, Cameron McCormack, Chris Marrin, Christophe Jolif, Charles McCathieNevile, Dan Winship, David Andersson, David Flanagan, David Håsäther, David Levin, Dean Jackson, Denis Sureau, Doug Schepers, Douglas Livingstone, Elliotte Harold, Eric Lawrence, Eric Uhrhane, Erik Dahlström, Geoffrey Sneddon, Gideon Cohn, Glenn Adams, Gorm Haug Eriksen, Håkon Wium Lie, Hallvord R. M. Steen, Henri Sivonen, Huub Schaeks, Ian Davis, Ian Hickson, Ivan Herman, Jarred Nicholls, Jeff Walden, Jens Lindström, Jim Deegan, Jim Ley, Joe Farro, Jonas Sicking, Julian Reschke, 呂康豪 (Kang-Hao Lu), Karl Dubost, Lachlan Hunt, Maciej Stachowiak, Magnus Kristiansen, Marc Hadley, Marcos Caceres, Mark Baker, Mark Birbeck, Mark Nottingham, Mark S. Miller, Martin Hassman, Mohamed Zergaoui, Ms2ger, Odin Hørthe Omdal, Olli Pettay, Pawel Glowacki, Peter Michaux, Philip Taylor, Robin Berjon, Rune Halvorsen, Ruud Steltenpool, Sergiu Dumitriu, Sigbjørn Finne, Simon Pieters, Stewart Brodie, Sunava Dutta, Thomas Roessler, Tom Magliery, Yehuda Katz, and Zhenbin Xu for their contributions to this specification.

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 also to the WHATWG for drafting an initial version of this specification in their Web Applications 1.0 document (now renamed to HTML). [HTML]

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

Thanks also to all those who have helped to improve this specification by sending suggestions and corrections. (Please, keep bugging us with your issues!)