W3C

The XMLHttpRequest Object

W3C Working Draft 27 September 2006

This Version:
http://www.w3.org/TR/2006/WD-XMLHttpRequest-20060927/
Latest Version:
http://www.w3.org/TR/XMLHttpRequest/
Previous Versions:
http://www.w3.org/TR/2006/WD-XMLHttpRequest-20060619/
http://www.w3.org/TR/2006/WD-XMLHttpRequest-20060405/
Editor:
Anne van Kesteren (Opera Software ASA) <annevk@opera.com>

Abstract

This specification defines the XMLHttpRequest object, an API that provides additional HTTP client functionality for transferring data between a client and a server.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This is the third Working Draft of The XMLHttpRequest Object. This document is produced by the Web APIs WG, part of the Rich Web Clients Activity in the W3C Interaction Domain.

Web content and browser developers are encouraged to review this draft. Please send comments to public-webapi@w3.org, the W3C's public email list for issues related to Web APIs. Archives of the list are available.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1. Introduction

This section is non-normative.

The XMLHttpRequest object is an interface exposed by a scripting engine that allows scripts to perform HTTP client functionality, such as submitting form data or loading data from a server.

The name of the object is XMLHttpRequest for compatibility with the web as it doesn't make much sense otherwise. It supports the transport of other data formats in addition to XML, some implementations support other protocols besides HTTP (that functionality is not covered in this specification though) and the API supports sending data as well.

1.1. History

This section is non-normative.

The XMLHttpRequest object has been implemented for many years as ActiveX control in the Windows Internet Explorer browser and has later been adopted by other popular web browsers. Unfortunately the current implementations are not completely interoperable. Based on those early implementations this specification defines how a common subset of XMLHttpRequest should work and this will probably result in changes in said implementations leading to more interoperable and useful implementations of the XMLHttpRequest object.

Future versions of this specification (as opposed to future drafts of this version) may add new features, after careful examination from browser developers and Web content developers.

1.2. Examples of Usage

This section is non-normative.

Various [ECMAScript] examples are listed throughout the specification. In addition, you can find some below.

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

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

function handler() {
 if(this.readyState == 4 && this.status == 200) {
  // so far so good
  if(this.responseXML != null && this.responseXML.getElementById('test').firstChild.data)
   // success!
   test(this.responseXML.getElementById('test').firstChild.data);
  else
   test(null);
 } else if (this.readyState == 4 && this.status != 200) {
  // fetched the wrong page or network error...
  test(null);
 }
}

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

If you just want to ping the server with a message you could do something like:

function ping(message) {
 var client = new XMLHttpRequest();
 client.open("POST", "/ping");
 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 == 4)
   returnStatus(this.status);
 }
 client.open("HEAD", address);
 client.send();
}

1.3. Conformance

Everying in this specification is normative except for diagrams, examples, notes and sections marked non-normative.

The key words must, must not, required, shall, shall not, should, should not, recommended, may and optional in this document are to be interpreted as described in RFC 2119 [RFC2119].

This specification defines the following classes of products:

conforming implementation
A user agent that implements all interfaces described in this specification and follows all must-, required- and shall-level of critera in this specification.
conforming document
A document that follows all must-, required- and shall-level of critera in this specification that apply to document authors.
conforming authoring tool
One that produces conforming documents.

1.4. Extensibility

This section is non-normative.

Extensions of the APIs defined in this specification are strongly discouraged. User agents, Working Groups and other interested parties should discuss extensions on a relevant public forum, such as public-webapi@w3.org.

1.5. Not in this Specification

This section is non normative.

This specification does not include the following features that may or may not be implemented by user agents:

2. The XMLHttpRequest Object

What if the user cancels a request by leaving the page? How does that work for multiple windows and what's the effect on the object? Need to test.

The XMLHttpRequest interface may be used to allow scripts to programmatically connect to their originating server via HTTP.

Objects implementing the XMLHttpRequest interface must also implement the EventTarget interface [DOM3Events].

In [ECMAScript], an instance of XMLHttpRequest can be created using the XMLHttpRequest() constructor:

var client = new XMLHttpRequest();

2.1. The XMLHttpRequest IDL

This section is non-normative.

A more complete description of what can be done with XMLHttpRequest can be found in the IDL below and its associated details. It's non-normative and does not conform to [OMGIDL]. Only the language bindings are normative.

interface XMLHttpRequest {
           attribute EventListener   onreadystatechange;
  readonly attribute unsigned short  readyState;
  void               open(in DOMString method, in DOMString url);
  void               open(in DOMString method, in DOMString url, in boolean async);
  void               open(in DOMString method, in DOMString url, in boolean async, in DOMString user);
  void               open(in DOMString method, in DOMString url, in boolean async, in DOMString user, in DOMString password);
  void               setRequestHeader(in DOMString header, in DOMString value);
  void               send();
  void               send(in DOMString data);
  void               send(in Document data);
  void               abort();
  DOMString          getAllResponseHeaders();
  DOMString          getResponseHeader(in DOMString header);
  readonly attribute DOMString       responseText;
  readonly attribute Document        responseXML;
  readonly attribute unsigned short  status;
  readonly attribute DOMString       statusText;
};

2.2. Members of the XMLHttpRequest Object

onreadystatechange of type EventListener

An attribute that takes an EventListener as value that must be invoked when readystatechange is dispatched on the object implementing the XMLHttpRequest interface. Its initial value must be null.

readyState of type unsigned short, readonly

The state of the object. The attribute must be one of the following values:

0 Uninitialized
The initial value.
1 Open
The open() method has been successfully called.
2 Sent
The user agent successfully acknowledged the request.
3 Receiving
Immediately before receiving the message body (if any). All HTTP headers have been received.
4 Loaded
The data transfer has been completed.
open(method, url, async, user, password), method

What about multiple open() invocations? Like behind each other or one after invoking send(), etc.

Calling this method must initialize the object by remembering the method, url, async (defaulting to true if omitted), user (defaulting to null if omitted), and password (defaulting to null if omitted) arguments, setting the readyState attribute to 1 (Open), resetting the responseText, responseXML, status, and statusText attributes to their initial values, and resetting the list of request headers.

Same-origin security restrictions should apply.

If the method argument doesn't match the method production defined in section 5.1.1 of [RFC2616] a SYNTAX_ERR must be raised by the user agent. If the user agent doesn't support the given method for security reasons a SECURITY_ERR should be raised.

User agents must at least support the following list of methods (see [RFC2616], [RFC2518], [RFC3253], [RFC3648] and [RFC3744]):

User agents should support any method argument that matches the method production.

When method case-insensitively matches GET, POST, HEAD, PUT or DELETE the user agent must use the uppercase equivalent instead.

If the url parameter doesn't match the syntax defined in section 3.2.2 of [RFC2616] a SYNTAX_ERR must be raised. When a non same-origin url argument is given user agents should throw a SECURITY_ERR exception.

A future version or extension of this specification will define a way of doing cross-site requests.

User agents should not support the "user:password" format in the userinfo production defined in section 3.2.1 of [RFC3986] and must throw a SYNTAX_ERR when doing so (not supporting it). When they do support it, or in case of people using the format "user", user agents must use them if the user and password arguments are omitted. If the arguments are not omitted, they take precedence, even if they are null.

If the user argument doesn't match the username-value production defined in section 3.2.2 of [RFC2617] user agents must throw a SYNTAX_ERR exception.

Need to look at the password argument.

If open() is invoked when readyState is 4 (Loaded) all members of the object must be set to their initial values.

setRequestHeader(header, value), method

This should probably say that it can only be invoked between the invocation of open() and the invocation of send() given that readyState doesn't accurately reflects that period.

The nominated request header (header) field value must be set to value, with the following exceptions:

Implementations must replace any existing value if the nominated request header field value is one of: Authorization, Content-Base, Content-Location, Content-MD5, Content-Range, Content-Type, Content-Version, Delta-Base, Depth, Destination, ETag, Expect, From, If-Modified-Since, If-Range, If-Unmodified-Since, Max-Forwards, MIME-Version, Overwrite, Proxy-Authorization, SOAPAction or Timeout.

Otherwise, if the nominated request header field already has a value, the new value must be combined with the existing value (section 4.2, [RFC2616]). See also the send() method regarding user agent header handling for caching, authentication, proxies, and cookies.

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

// ...would result in the following header being sent:
...
X-Test: one, two
...

The list of request headers must be reset when the open() method is invoked.

send(data), method

What about multiple send() invocations? Note that invoking send() doesn't change readyState directly which makes this tricky.

If the readyState attribute has a value other than 1 (Open), an INVALID_STATE_ERR exception must be raised. Otherwise, a request to url using method method is sent. url, if relative, must be resolved using window.document.baseURI of the window whose constructor is used. If the async flag is set to false, then the method must not return until the request has completed. Otherwise, it must return immediately. (See: open().)

If data is passed to the send() method it must be used for the entity body following these rules (the term entity body is defined by section 7.2.1 of [RFC2616]):

Invoking send() without the data argument must give the same result as if it was invoked with null as argument.

Authors should specify the Content-Type header via setRequestHeader before invoking send() with an argument. If the argument to send() is a Document and no Content-Type header has been set user agents must set it to application/xml for XML documents and to the most appropriate media type for other documents (using intrinsic knowledge about the document).

If the response is an HTTP redirect (status code 301, 302, 303 or 307), then it must be transparently followed (unless it violates security, infinite loop precautions or the scheme isn't supported). Note that HTTP ([RFC2616]) places requirements on user agents regarding the preservation of the request method during redirects, and also requires users to be notified of certain kinds of automatic redirections.

Once the request has been successfully acknowledged readyState must be set to 2 (Sent). Immediately before receiving the message body (if any), the readyState attribute must be set to to 3 (Receiving). When the request has completed loading, the readyState attribute must be set to 4 (Loaded). In case of a HEAD request readyState must be set to 4 (Loaded) immediately after having gone to 3 (Receiving).

If something goes wrong (infinite loop, network errors) the readyState attribute must be set to 4 (Loaded) and all other members of the object must be set to their initial value.

In future versions of this specification user agents will be required to dispatch an error event if the above occurs.

If the user agent allows the specification of 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 ([RFC2617]) it should consider requests originating from this object to be part of the protection space that includes the accessed URIs and send Authorization headers and handle 401 Unauthorised requests appropriately. if authentication fails, user agents should prompt the users for credentials.

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

If the user agent implements a HTTP cache ([RFC2616]) it should respect Cache-Control request headers set by the author (e.g., Cache-Control: no-cache bypasses the cache). It must not send Cache-Control or Pragma request headers automatically unless the user explicitly requests such behaviour (e.g., by (force-)reloading the page). 304 Not Modified responses that are a result of a user agent generated conditional request must be presented as 200 OK responses with the appropriate content. Such user agents must allow authors to override automatic cache validation by setting request headers (e.g., If-None-Match, If-Modified-Since), in which case 304 Not Modified responses must be passed through.

If the user agent implements server-driven content-negotiation ([RFC2616]) it should set Accept-Language, Accept-Encoding and Accept-Charset headers as appropriate; it must not automatically set the Accept header. Responses to such requests must have content-codings automatically removed.

If the user agent supports Expect/Continue for request bodies ([RFC2616]) it should insert Expect headers and handle 100 Continue responses appropriately.

abort(), method

When invoked, this method must cancel any network activity for which the object is responsible and set all the members of the object to their initial values.

getAllResponseHeaders(), method

If the readyState attribute has a value other than 3 (Receiving) or 4 (Loaded), user agents must raise an INVALID_STATE_ERR exception. Otherwise, it must return all the HTTP headers, as a single string, with each header line separated by a CR (U+000D) LF (U+000A) pair. The status line must not be included.

// The following script:
var client = new XMLHttpRequest();
client.open("GET", "test.txt", true);
client.send();
client.onreadystatechange = function() {
 if(this.readyState == 3) {
  print(this.getAllResponseHeaders());
 }
}

// ...should output something similar to the following text:
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
getResponseHeader(header), method

If the header argument doesn't match the field-name production a SYNTAX_ERR must be raised. Otherwise this method works as described below.

If the readyState attribute has a value other than 3 (Receiving) or 4 (Loaded), the user agent must raise an INVALID_STATE_ERR exception. Otherwise, it must represent the value of the given HTTP header (header) in the data received so far for the last request sent, as a single string. If more than one header of the given name was received, then the values must be concatenated, separated from each other by an U+002C COMMA followed by an U+0020 SPACE. If no headers of that name were received, then it must return null. Header names must be compared case-insensitively to the method its argument (header).

// The following script:
var client = new XMLHttpRequest();
client.open("GET", "test.txt", true);
client.send();
client.onreadystatechange = function() {
 if(this.readyState == 3) {
  print(client.getResponseHeader("Content-Type"));
 }
}

// ...should output something similar to the following text:
Content-Type: text/plain; charset=utf-8
responseText of type DOMString, readonly

If the readyState attribute has a value other than 3 (Receiving) or 4 (Loaded), the user agent must raise an INVALID_STATE_ERR exception. Otherwise, it must be the fragment of the entity body received so far (when readyState is 3 (Receiving)) or the complete entity body (when readyState is 4 (Loaded)), interpreted as a stream of characters.

If the response includes a Content-Type understood by the user agent the characters are encoded following the relevant media type specification, with the exception that the rule in the final paragraph of section 3.7.1 of [RFC2616], and the rules in section 4.1.2 of [RFC2046] must be treated as if they specified the default character encoding as being UTF-8. Invalid bytes must be converted to U+FFFD REPLACEMENT CHARACTER. If the user agent can't derive a character stream in accord with the media type specification, reponseText must be null.

Its initial value must be the null.

responseXML of type Document, readonly

If the readyState attribute has a value other than 4 (Loaded), user agents must raise an INVALID_STATE_ERR exception. Otherwise, if the Content-Type header contains a media type (ignoring any parameters) that is either text/xml, application/xml, or ends in +xml, it must be an object that implements the Document interface representing the parsed document. If Content-Type did not contain such a media type, or if the document could not be parsed (due to an XML well-formedness error or unsupported character encoding, for instance), it must be null.

Its initial value must be null.

status of type unsigned short, readonly

If the status attribute is not available an INVALID_STATE_ERR exception must be raised. It must be available when readyState is 3 (Receiving) or 4 (Loaded). When available, it must represent the HTTP status code (typically 200 for a successful connection).

Its initial value must be 0.

statusText of type DOMString, readonly

If the statusText attribute is not available an INVALID_STATE_ERR exception must be raised. It must be available when readyState is 3 (Receiving) or 4 (Loaded). When available, it must represent the HTTP status text sent by the server (appears after the status code).

Its initial value must be the empty string.

HTTP requests sent from multiple different XMLHttpRequest objects in succession should be pipelined into shared HTTP connections.

2.3. Events for the XMLHttpRequest Object

These sections describe the various events that can be dispatched on the object implementing the XMLHttpRequest interface. For this version of the specification only one event is defined.

readystatechange
The readystatechange event must be dispatched when readyState changes value. It must not bubble, must not be cancelable and must implement the Event interface [DOM3Events]. The event has no namespace (Event.namespaceURI is null).

References

[DOM3Core]
Document Object Model (DOM) Level 3 Core Specification, A. Le Hors, P. Le Hégaret, L. Wood, G. Nicol, J. Robie, M. Champion, S. Byrne, editors. World Wide Web Consortium, April 2004.
[DOM3Events]
Document Object Model (DOM) Level 3 Events Specification, Björn Höhrmann, editor. World Wide Web Consortium, April 2006.
[ECMAScript]
ECMAScript Language Specification, Third Edition. ECMA, December 1999.
[RFC2046]
Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types, N. Freed, N. Borenstein, editors. IETF, November 1996.
[RFC2109]
HTTP State Management Mechanism, D. Kristol, L. Montulli, editors. IETF, February 1997.
[RFC2119]
RFC 2119: Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF, March 1997.
[RFC2518]
HTTP Extensions for Distributed Authoring -- WEBDAV, Y. Goland, E. Whitehead, A. Faizi, S. Carter, D. Jensen, editors. IETF, February 1999.
[RFC2616]
Hypertext Transfer Protocol -- HTTP/1.1, R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee, editors. IETF, June 1999
[RFC2617]
HTTP Authentication: Basic and Digest Access Authentication, ...
[RFC2965]
HTTP State Management Mechanism, D. Kristol, L. Montulli, editors. IETF, October 2000.
[RFC3253]
Versioning Extensions to WebDAV, G. Clemm, J. Amsden, T. Ellison, C. Kaler, J. Whitehead, editors. IETF, March 2002.
[RFC3648]
Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol, J. Whitehead, J. Reschke, editors. IETF, December 2003.
[RFC3744]
Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol, G. Clemm, J. Reschke, E. Sedlar, J. Whitehead, editors. IETF, May 2004.
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax, T. Berners-Lee, R. Fielding, L. Masinter, editors. IETF, January 2005.

Acknowledgements

This section is non-normative

The editor would like to thank to the following people who have contributed to this specification (ordered on first name):

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 a first version of this specification in their Web Applications 1.0 document.

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