From e40f7ad686b9eda962ae5aaba61812196fa005c5 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Mon, 16 Aug 2021 09:03:20 +0200 Subject: [PATCH 01/32] Review Draft Publication: August 2021 --- review-drafts/2021-08.bs | 2011 ++++++++++++++++++++++++++++++++++++++ xhr.bs | 2 +- 2 files changed, 2012 insertions(+), 1 deletion(-) create mode 100644 review-drafts/2021-08.bs diff --git a/review-drafts/2021-08.bs b/review-drafts/2021-08.bs new file mode 100644 index 0000000..76a3b9c --- /dev/null +++ b/review-drafts/2021-08.bs @@ -0,0 +1,2011 @@ +
+Group: WHATWG
+Date: 2021-08-16
+H1: XMLHttpRequest
+Shortname: xhr
+Text Macro: TWITTER xhrstandard
+Text Macro: LATESTRD 2021-08
+Abstract: The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server.
+Translation: ja https://triple-underscore.github.io/XHR-ja.html
+Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue
+
+ +
+urlPrefix: https://w3c.github.io/DOM-Parsing/; spec: dom-parsing
+    type: dfn; text: fragment serializing algorithm; url: dfn-fragment-serializing-algorithm
+
+ + + +

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();
+}
+
+ + +

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: + +

+ + + +

Terminology

+ +

This specification depends on the Infra Standard. [[!INFRA]] + +

This specification uses terminology from DOM, DOM Parsing and Serialization, Encoding, +Fetch, File API, HTML, URL, Web IDL, and XML. + +[[!DOM]] +[[!DOM-PARSING]] +[[!ENCODING]] +[[!FETCH]] +[[!FILEAPI]] +[[!HTML]] +[[!URL]] +[[!WEBIDL]] +[[!XML]] [[!XML-NAMES]] + + + +

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

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

+ + +

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

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 +
+ + +

States

+ +
+
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). +
+ + +

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.) + + +

The open() method

+ +
+
client . open(method, url [, async = true [, username = null [, password = null]]]) + +
+

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

Throws a "{{SyntaxError!!exception}}" {{DOMException}} if either method is not a + valid method or url cannot be parsed. + +

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

Throws an "{{InvalidAccessError!!exception}}" {{DOMException}} if async is false, + current global object is a {{Window}} object, and the {{XMLHttpRequest/timeout!!attribute}} + attribute is not zero or the {{XMLHttpRequest/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!!exception}}" {{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!!exception}}" {{DOMException}}. + +

  3. If method is not a method, then throw a + "{{SyntaxError!!exception}}" {{DOMException}}. + +

  4. If method is a forbidden method, then throw a + "{{SecurityError!!exception}}" {{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!!exception}}" + {{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!!exception}}" {{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. + + + +

The setRequestHeader() method

+ +
+
client . setRequestHeader(name, value) + +
+

Combines a header in author request headers. + +

Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if either state is not + opened or the send() flag is set. + +

Throws a "{{SyntaxError!!exception}}" {{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!!exception}}" {{DOMException}}. + +

  2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

  3. Normalize value. + +

  4. +

    If name is not a name or value is not a + value, then throw a "{{SyntaxError!!exception}}" {{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
+
+ + +

The timeout getter and setter

+ +
+
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!!exception}}" {{DOMException}} will be thrown otherwise (for the + send() method). + +

When set: throws an "{{InvalidAccessError!!exception}}" {{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 {{XMLHttpRequest/timeout!!attribute}} setter steps are: + +

    +
  1. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

  2. Set this's timeout to the given value. +

+ +

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

The withCredentials getter and setter

+ +
+
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!!exception}}" {{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 {{XMLHttpRequest/withCredentials}} setter steps are: + +

    +
  1. If this's state is not unsent or opened, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

  2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

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

+ + +

The upload getter

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

The send() method

+ +
+
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!!exception}}" {{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!!exception}}" {{DOMException}}. + +

  2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{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. +
    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. Let requestBodyTransmitted be 0. + +

    3. Let requestBodyLength be req's body's + length, if req's body is non-null; otherwise 0. + +

    4. Assert: requestBodyLength is an integer. + +

    5. 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 + requestBodyTransmitted and requestBodyLength. + +

    6. If this's state is not opened or this's + send() flag is unset, then return. + +

    7. +

      Let processRequestBody, given a bytesLength, be these steps: + +

        +
      1. Increase requestBodyTransmitted by bytesLength. + +

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

      3. If this's upload listener flag is set, then fire a progress event + named progress at this's upload object with + requestBodyTransmitted and requestBodyLength. + +

      + +

      These steps are only invoked when new bytes are transmitted. + +

    8. +

      Let processRequestEndOfBody be these steps: + +

        +
      1. Set this's upload complete flag. + +

      2. If this's upload listener flag is unset, then return. + +

      3. Fire a progress event named progress at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

      4. Fire a progress event named load at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

      5. Fire a progress event named loadend at this's + upload object with requestBodyTransmitted and requestBodyLength. +

      + + +
    9. +

      Let processResponse, given a response, be these steps: + +

        +
      1. Set this's response to response. + +

      2. Handle errors for this. + +

      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 return. + +

      8. Let length be the result of extracting a length from + this's response's header list. + +

      9. If length is not an integer, then set it to 0. + +

      10. +

        Let processBodyChunk given bytes be these steps: + +

          +
        1. Append bytes to this's received bytes. + +

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

        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 received bytes's length and + length. +

        + +
      11. Let processEndOfBody be this step: run handle response end-of-body for + this. + +

      12. +

        Let processBodyError be these steps: + +

          +
        1. Set this's response to a network error. + +

        2. Run handle errors for this. +

        + +
      13. Incrementally read this's response's + body, given processBodyChunk, processEndOfBody, + processBodyError, and this's relevant global object. +

      + +
    10. Fetch req with processRequestBody set to + processRequestBody, processRequestEndOfBody set to + processRequestEndOfBody, and processResponse set to + processResponse. + +

    11. Let now be the present time. + + +

    12. +

      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 + now. + +

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

      +
    + +
  12. +

    Otherwise, if this's synchronous flag is set: + +

      +
    1. Let processedResponse be false. + +

    2. +

      Let processResponseEndOfBody, given a response and + nullOrFailureOrBytes, be these steps: + +

        +
      1. If nullOrFailureOrBytes is not failure, then set this's + response to response. + +

      2. If nullOrFailureOrBytes is a byte sequence, then append + nullOrFailureOrBytes to this's received bytes. + +

      3. Set processedResponse to true. +

      + +
    3. Fetch req with processResponseEndOfBody + set to processResponseEndOfBody and useParallelQueue set to + true. + +

    4. Let now be the present time. + + +

    5. Pause until either processedResponse is true or this's + timeout is not 0 and this's timeout milliseconds have passed since + now. + +

    6. If processedResponse is false, then set this's timed out flag and + terminate fetching. + +

    7. Run handle response end-of-body for this. +

    +
+ +

To handle response end-of-body for an +{{XMLHttpRequest}} object xhr, run these steps: + +

    +
  1. Handle errors for xhr. + +

  2. If xhr's response is a network error, then + return. + +

  3. Let transmitted be xhr's received bytes's + length. + +

  4. Let length be the result of extracting a length from + this's response's header list. + +

  5. If length is not an integer, then set it to 0. + +

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

  7. Set xhr's state to done. + +

  8. Unset xhr's send() flag. + +

  9. Fire an event named readystatechange at xhr. + +

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

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

+ +

To handle errors for an {{XMLHttpRequest}} object xhr, 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!!exception}}" + {{DOMException}}. + +

  3. Otherwise, if xhr's response's + aborted flag is set, run the request error steps for xhr, + abort, and "{{AbortError!!exception}}" {{DOMException}}. + +

  4. Otherwise, if xhr's response's is a + network error, run the request error steps for xhr, + error, and "{{NetworkError!!exception}}" {{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. +

+ + +

The abort() method

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

+ + +

Response

+ +

The responseURL getter

+ +

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

The status getter

+ +

The status getter steps are to return +this's response's status. + + +

The statusText getter

+ +

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

The getResponseHeader() method

+ +

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
+
+ + +

The getAllResponseHeaders() method

+ +

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
+
+ + +

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

The overrideMimeType() method

+ +
+
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!!exception}}" {{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!!exception}}" {{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. +

+ + +

The responseType getter and setter

+ +
+
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!!exception}}" {{DOMException}} if state is + loading or done. + +

When set: throws an "{{InvalidAccessError!!exception}}" {{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 {{XMLHttpRequest/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!!exception}}" {{DOMException}}. + +

  3. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

  4. Set this's response type to the given value. +

+ + +

The response getter

+ +
+
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 {{Blob/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. +

+ + +

The responseText getter

+ +
+
client . responseText +
+

Returns response as text. + +

Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

+ + +

The responseXML getter

+ +
+
client . responseXML +
+

Returns the response as document. + +

Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

+ + +

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 {{XMLHttpRequest/readyState}} attribute changes + value, except when it changes to UNSENT. +
loadstart + {{ProgressEvent}} + The fetch initiates. +
progress + {{ProgressEvent}} + Transmitting data. +
abort + {{ProgressEvent}} + When the fetch has been aborted. For instance, by invoking the + {{XMLHttpRequest/abort()}} method. +
error + {{ProgressEvent}} + The fetch failed. +
load + {{ProgressEvent}} + The fetch succeeded. +
timeout + {{ProgressEvent}} + The author specified timeout has passed before the fetch completed. +
loadend + {{ProgressEvent}} + The fetch completed (success or failure). +
+ + +

Interface {{FormData}}

+ +
+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 {{File/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 {{File/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 {{File/name}} + attribute value is filename. + +

  5. Set entry's value to value. + +

  6. Return entry. +

+ +
+ +

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!!exception}}" + {{DOMException}}. + +

    3. Set this's entry list to list. +

    +
+ +

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

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

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

+ +

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

+ +

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

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

Interface {{ProgressEvent}}

+ +
+[Exposed=(Window,Worker)]
+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. + +

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

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 {{ProgressEvent/loaded}} +attribute initialized to transmitted, and if length is not 0, with the +{{ProgressEvent/lengthComputable}} attribute initialized to true and the {{ProgressEvent/total}} +attribute initialized to length. + + +

Suggested names for events using the {{ProgressEvent}} interface

+ +

This section is non-normative. + +

The suggested {{Event/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. + + + + + + + + + + + +
{{Event/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 {{Event/bubbles}} and {{Event/cancelable}} +attributes initialized to false, so it is suggested that for consistency all +events using the +{{ProgressEvent}} interface do the same. + + +

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]] + + +

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, +Rashika Jaggi, +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). diff --git a/xhr.bs b/xhr.bs index 9ab006b..c827f46 100644 --- a/xhr.bs +++ b/xhr.bs @@ -3,7 +3,7 @@ Group: WHATWG H1: XMLHttpRequest Shortname: xhr Text Macro: TWITTER xhrstandard -Text Macro: LATESTRD 2021-02 +Text Macro: LATESTRD 2021-08 Abstract: The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server. Translation: ja https://triple-underscore.github.io/XHR-ja.html Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue From 248cd8e5dbabc7d188a298f640d6048e9f66c80a Mon Sep 17 00:00:00 2001 From: Chirag <40859110+Fictionistique@users.noreply.github.com> Date: Tue, 19 Oct 2021 13:19:32 +0530 Subject: [PATCH 02/32] Editorial: rename processRequestBody See https://github.com/whatwg/fetch/issues/1320 for context. --- xhr.bs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xhr.bs b/xhr.bs index c827f46..ce13e4e 100644 --- a/xhr.bs +++ b/xhr.bs @@ -798,7 +798,7 @@ return this's cross-origin credentials. send() flag is unset, then return.

  • -

    Let processRequestBody, given a bytesLength, be these steps: +

    Let processRequestBodyChunkLength, given a bytesLength, be these steps:

    1. Increase requestBodyTransmitted by bytesLength. @@ -896,8 +896,9 @@ return this's cross-origin credentials. processBodyError, and this's relevant global object.

    -
  • Fetch req with processRequestBody set to - processRequestBody, processRequestEndOfBody set to +

  • Fetch req with + processRequestBodyChunkLength set to + processRequestBodyChunkLength, processRequestEndOfBody set to processRequestEndOfBody, and processResponse set to processResponse. @@ -1902,6 +1903,7 @@ Cameron McCormack, Chris Marrin, Christophe Jolif, Charles McCathieNevile, +Chirag S Kumar, Dan Winship, David Andersson, David Flanagan, From 0da655e927ffd9675269c6ad4c60bd62e33d8f86 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Mon, 25 Oct 2021 10:26:57 +0200 Subject: [PATCH 03/32] Meta: remove class=no-backref This leaves one that #334 will tackle. --- xhr.bs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/xhr.bs b/xhr.bs index ce13e4e..5ebd567 100644 --- a/xhr.bs +++ b/xhr.bs @@ -384,10 +384,10 @@ cell in the first column is this's state:

    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.) +

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

    The open() method

    @@ -410,11 +410,11 @@ turn causes the use-CORS-preflight flag to be set.) attribute is not zero or the {{XMLHttpRequest/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 +

    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!!exception}}" {{DOMException}} when it occurs.

    The @@ -1102,8 +1102,8 @@ set. 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]] +

    The Fetch Standard filters this's response's +header list. [[!FETCH]]

    For the following script: @@ -1161,8 +1161,8 @@ text/plain; charset=UTF-8

  • Return output. -

    The Fetch Standard filters this's -response's header list. [[!FETCH]] +

    The Fetch Standard filters this's response's +header list. [[!FETCH]]

    For the following script: From 88a61d5d582eeee2bcd3faaa75672000b8db6f90 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Tue, 26 Oct 2021 16:48:25 +0200 Subject: [PATCH 04/32] Editorial: align with Fetch's change to tuples See https://github.com/whatwg/fetch/pull/1339 for context. --- xhr.bs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/xhr.bs b/xhr.bs index 5ebd567..00b3eb7 100644 --- a/xhr.bs +++ b/xhr.bs @@ -535,18 +535,17 @@ method must run these steps:

  • If this's send() flag is set, then throw an "{{InvalidStateError!!exception}}" {{DOMException}}. -

  • Normalize value. +

  • Normalize value.

  • -

    If name is not a name or value is not a - value, then throw a "{{SyntaxError!!exception}}" {{DOMException}}. +

    If name is not a header name or value is not a + header value, then throw a "{{SyntaxError!!exception}}" {{DOMException}}. -

    An empty byte sequence represents an empty header - value. +

    An empty byte sequence represents an empty header value.

  • If name is a forbidden header name, then return. -

  • Combine name/value in this's +

  • Combine (name, value) in this's author request headers. @@ -709,9 +708,8 @@ return this's cross-origin credentials.

  • Let newContentTypeSerialized be the result of serializing contentTypeRecord. -

  • Set - `Content-Type`/newContentTypeSerialized in this's - author request headers. +

  • Set (`Content-Type`, + newContentTypeSerialized) in this's author request headers. @@ -720,16 +718,16 @@ return this's cross-origin credentials.

    Otherwise:

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

    2. If body is an HTML document, then set + (`Content-Type`, `text/html;charset=UTF-8`) in this's author request headers.

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

    4. Otherwise, if extractedContentType is not null, set - `Content-Type`/extractedContentType in this's + (`Content-Type`, extractedContentType) in this's author request headers.

    From 1dc9103797451fb7365ba46e3c4763e13d635357 Mon Sep 17 00:00:00 2001 From: Andreu Botella Date: Tue, 30 Nov 2021 09:57:09 +0100 Subject: [PATCH 05/32] Editorial: use HTML's definitions of "entry list" and "entry" Companion to https://github.com/whatwg/html/pull/7371. --- xhr.bs | 46 ++++++++++------------------------------------ 1 file changed, 10 insertions(+), 36 deletions(-) diff --git a/xhr.bs b/xhr.bs index 00b3eb7..32dd843 100644 --- a/xhr.bs +++ b/xhr.bs @@ -1595,41 +1595,15 @@ interface FormData {

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

    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 {{File/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 {{File/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 {{File/name}} - attribute value is filename. - -

    5. Set entry's value to value. - -

    6. Return entry. -

    - -
    +

    This section used to define +entry, an entry's +name and +value, and the +create an entry algorithm. These definitions have been +moved to the HTML Standard. [[HTML]]

    The new FormData(form) @@ -1659,7 +1633,7 @@ method steps are:

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

    2. Let entry be the result of creating an entry with +

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

    4. Append entry to this's entry list. @@ -1710,7 +1684,7 @@ method steps are:

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

      2. Let entry be the result of creating an entry with +

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

      4. If there are entries in this's entry list From bdcd683e12bb6e244d198ea14dfdfc3fe9ac3047 Mon Sep 17 00:00:00 2001 From: Andreu Botella Date: Wed, 1 Dec 2021 10:51:36 +0100 Subject: [PATCH 06/32] Editorial: point the remaining entry list terms to HTML See #338 and https://github.com/whatwg/html/pull/7371. --- xhr.bs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/xhr.bs b/xhr.bs index 32dd843..270da57 100644 --- a/xhr.bs +++ b/xhr.bs @@ -1643,18 +1643,19 @@ method steps are: is due to a limitation of the editing software used to write the XMLHttpRequest Standard.

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

        The get(name) method steps are:

          -
        1. If there is no entry whose name is +

        2. If there is no entry whose name is name in this's entry list, then return null. -

        3. Return the value of the first entry whose - name is name from this's +

        4. Return the value of the first entry + whose name is name from this's entry list.

        @@ -1662,18 +1663,18 @@ steps are: method steps are:
          -
        1. If there is no entry whose name is +

        2. If there is no entry whose name is name in this's entry list, then return the empty list. -

        3. Return the values of all entries whose - name is name, in order, from this's +

        4. Return the values of all entries whose + name is name, in order, from this's entry list.

        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. +steps are to return true if there is an entry whose +name is name in this's +entry list; otherwise false.

        The set(name, value) @@ -1687,9 +1688,9 @@ method steps are:

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

      6. 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. +

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

      8. Otherwise, append entry to this's entry list. @@ -1699,8 +1700,8 @@ method steps are: 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. +entries with the key being the name and the +value being the value.

        Interface {{ProgressEvent}}

        From 76470338b3ac49cbe4d8d6f9274662b3fda8493b Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Mon, 13 Dec 2021 15:05:32 +0100 Subject: [PATCH 07/32] Editorial: align with Fetch renaming (The old) processResponseEndOfBody is now processResponseConsumeBody. See https://github.com/whatwg/fetch/pull/1369 for context. --- xhr.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xhr.bs b/xhr.bs index 270da57..d55bfa0 100644 --- a/xhr.bs +++ b/xhr.bs @@ -923,7 +923,7 @@ return this's cross-origin credentials.
      9. Let processedResponse be false.

      10. -

        Let processResponseEndOfBody, given a response and +

        Let processResponseConsumeBody, given a response and nullOrFailureOrBytes, be these steps:

          @@ -936,8 +936,8 @@ return this's cross-origin credentials.
        1. Set processedResponse to true.

        -
      11. Fetch req with processResponseEndOfBody - set to processResponseEndOfBody and useParallelQueue set to +

      12. Fetch req with processResponseConsumeBody + set to processResponseConsumeBody and useParallelQueue set to true.

      13. Let now be the present time. From b4da01a5f080e28a0f3447d5438036e9943754dc Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Fri, 11 Feb 2022 14:48:12 +0200 Subject: [PATCH 08/32] Resource Timing integration When response is a network error or body is fully read, finalize and report the response. Depends on https://github.com/whatwg/fetch/pull/1185. Also see https://github.com/w3c/resource-timing/pull/261 and https://github.com/w3c/resource-timing/issues/252. --- xhr.bs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/xhr.bs b/xhr.bs index d55bfa0..b7f5dfd 100644 --- a/xhr.bs +++ b/xhr.bs @@ -954,6 +954,10 @@ return this's cross-origin credentials.

    +

    To report timing for an {{XMLHttpRequest}} object xhr, +finalize and report timing with xhr's response, +xhr's relevant global object, and "xmlhttprequest". +

    To handle response end-of-body for an {{XMLHttpRequest}} object xhr, run these steps: @@ -963,6 +967,8 @@ return this's cross-origin credentials.

  • If xhr's response is a network error, then return. +

  • Report timing for xhr. +

  • Let transmitted be xhr's received bytes's length. @@ -1001,9 +1007,16 @@ return this's cross-origin credentials. aborted flag is set, run the request error steps for xhr, abort, and "{{AbortError!!exception}}" {{DOMException}}. -

  • Otherwise, if xhr's response's is a - network error, run the request error steps for xhr, - error, and "{{NetworkError!!exception}}" {{DOMException}}. +

  • +

    Otherwise, if xhr's response is a + network error, then: + +

      +
    1. Report timing for xhr. + +

    2. Run the request error steps for xhr, + error, and "{{NetworkError!!exception}}" {{DOMException}}. +

    The request error steps for an {{XMLHttpRequest}} object xhr, From 417436331ded9cbe883ae21bc5263fd15dfb5bfd Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Mon, 21 Feb 2022 11:36:09 +0100 Subject: [PATCH 09/32] Review Draft Publication: February 2022 --- review-drafts/2022-02.bs | 1999 ++++++++++++++++++++++++++++++++++++++ xhr.bs | 2 +- 2 files changed, 2000 insertions(+), 1 deletion(-) create mode 100644 review-drafts/2022-02.bs diff --git a/review-drafts/2022-02.bs b/review-drafts/2022-02.bs new file mode 100644 index 0000000..6ab0ab2 --- /dev/null +++ b/review-drafts/2022-02.bs @@ -0,0 +1,1999 @@ +

    + +
    +urlPrefix: https://w3c.github.io/DOM-Parsing/; spec: dom-parsing
    +    type: dfn; text: fragment serializing algorithm; url: dfn-fragment-serializing-algorithm
    +
    + + + +

    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();
    +}
    +
    + + +

    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: + +

    + + + +

    Terminology

    + +

    This specification depends on the Infra Standard. [[!INFRA]] + +

    This specification uses terminology from DOM, DOM Parsing and Serialization, Encoding, +Fetch, File API, HTML, URL, Web IDL, and XML. + +[[!DOM]] +[[!DOM-PARSING]] +[[!ENCODING]] +[[!FETCH]] +[[!FILEAPI]] +[[!HTML]] +[[!URL]] +[[!WEBIDL]] +[[!XML]] [[!XML-NAMES]] + + + +

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

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

    + + +

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

    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 +
    + + +

    States

    + +
    +
    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). +
    + + +

    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.) + + +

    The open() method

    + +
    +
    client . open(method, url [, async = true [, username = null [, password = null]]]) + +
    +

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

    Throws a "{{SyntaxError!!exception}}" {{DOMException}} if either method is not a + valid method or url cannot be parsed. + +

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

    Throws an "{{InvalidAccessError!!exception}}" {{DOMException}} if async is false, + current global object is a {{Window}} object, and the {{XMLHttpRequest/timeout!!attribute}} + attribute is not zero or the {{XMLHttpRequest/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!!exception}}" {{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!!exception}}" {{DOMException}}. + +

    3. If method is not a method, then throw a + "{{SyntaxError!!exception}}" {{DOMException}}. + +

    4. If method is a forbidden method, then throw a + "{{SecurityError!!exception}}" {{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!!exception}}" + {{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!!exception}}" {{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. + + + +

    The setRequestHeader() method

    + +
    +
    client . setRequestHeader(name, value) + +
    +

    Combines a header in author request headers. + +

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if either state is not + opened or the send() flag is set. + +

    Throws a "{{SyntaxError!!exception}}" {{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!!exception}}" {{DOMException}}. + +

    2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

    3. Normalize value. + +

    4. +

      If name is not a header name or value is not a + header value, then throw a "{{SyntaxError!!exception}}" {{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
    +
    + + +

    The timeout getter and setter

    + +
    +
    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!!exception}}" {{DOMException}} will be thrown otherwise (for the + send() method). + +

    When set: throws an "{{InvalidAccessError!!exception}}" {{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 {{XMLHttpRequest/timeout!!attribute}} setter steps are: + +

      +
    1. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

    2. Set this's timeout to the given value. +

    + +

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

    The withCredentials getter and setter

    + +
    +
    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!!exception}}" {{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 {{XMLHttpRequest/withCredentials}} setter steps are: + +

      +
    1. If this's state is not unsent or opened, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

    2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

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

    + + +

    The upload getter

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

    The send() method

    + +
    +
    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!!exception}}" {{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!!exception}}" {{DOMException}}. + +

    2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{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, then 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. +
      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. Let requestBodyTransmitted be 0. + +

      3. Let requestBodyLength be req's body's + length, if req's body is non-null; otherwise 0. + +

      4. Assert: requestBodyLength is an integer. + +

      5. 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 + requestBodyTransmitted and requestBodyLength. + +

      6. If this's state is not opened or this's + send() flag is unset, then return. + +

      7. +

        Let processRequestBodyChunkLength, given a bytesLength, be these steps: + +

          +
        1. Increase requestBodyTransmitted by bytesLength. + +

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

        3. If this's upload listener flag is set, then fire a progress event + named progress at this's upload object with + requestBodyTransmitted and requestBodyLength. + +

        + +

        These steps are only invoked when new bytes are transmitted. + +

      8. +

        Let processRequestEndOfBody be these steps: + +

          +
        1. Set this's upload complete flag. + +

        2. If this's upload listener flag is unset, then return. + +

        3. Fire a progress event named progress at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

        4. Fire a progress event named load at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

        5. Fire a progress event named loadend at this's + upload object with requestBodyTransmitted and requestBodyLength. +

        + + +
      9. +

        Let processResponse, given a response, be these steps: + +

          +
        1. Set this's response to response. + +

        2. Handle errors for this. + +

        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 return. + +

        8. Let length be the result of extracting a length from + this's response's header list. + +

        9. If length is not an integer, then set it to 0. + +

        10. +

          Let processBodyChunk given bytes be these steps: + +

            +
          1. Append bytes to this's received bytes. + +

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

          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 received bytes's length and + length. +

          + +
        11. Let processEndOfBody be this step: run handle response end-of-body for + this. + +

        12. +

          Let processBodyError be these steps: + +

            +
          1. Set this's response to a network error. + +

          2. Run handle errors for this. +

          + +
        13. Incrementally read this's response's + body, given processBodyChunk, processEndOfBody, + processBodyError, and this's relevant global object. +

        + +
      10. Fetch req with + processRequestBodyChunkLength set to + processRequestBodyChunkLength, processRequestEndOfBody set to + processRequestEndOfBody, and processResponse set to + processResponse. + +

      11. Let now be the present time. + + +

      12. +

        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 + now. + +

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

        +
      + +
    12. +

      Otherwise, if this's synchronous flag is set: + +

        +
      1. Let processedResponse be false. + +

      2. +

        Let processResponseConsumeBody, given a response and + nullOrFailureOrBytes, be these steps: + +

          +
        1. If nullOrFailureOrBytes is not failure, then set this's + response to response. + +

        2. If nullOrFailureOrBytes is a byte sequence, then append + nullOrFailureOrBytes to this's received bytes. + +

        3. Set processedResponse to true. +

        + +
      3. Fetch req with processResponseConsumeBody + set to processResponseConsumeBody and useParallelQueue set to + true. + +

      4. Let now be the present time. + + +

      5. Pause until either processedResponse is true or this's + timeout is not 0 and this's timeout milliseconds have passed since + now. + +

      6. If processedResponse is false, then set this's timed out flag and + terminate fetching. + +

      7. Run handle response end-of-body for this. +

      +
    + +

    To report timing for an {{XMLHttpRequest}} object xhr, +finalize and report timing with xhr's response, +xhr's relevant global object, and "xmlhttprequest". + +

    To handle response end-of-body for an +{{XMLHttpRequest}} object xhr, run these steps: + +

      +
    1. Handle errors for xhr. + +

    2. If xhr's response is a network error, then + return. + +

    3. Report timing for xhr. + +

    4. Let transmitted be xhr's received bytes's + length. + +

    5. Let length be the result of extracting a length from + this's response's header list. + +

    6. If length is not an integer, then set it to 0. + +

    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, 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!!exception}}" + {{DOMException}}. + +

    3. Otherwise, if xhr's response's + aborted flag is set, run the request error steps for xhr, + abort, and "{{AbortError!!exception}}" {{DOMException}}. + +

    4. +

      Otherwise, if xhr's response is a + network error, then: + +

        +
      1. Report timing for xhr. + +

      2. Run the request error steps for xhr, + error, and "{{NetworkError!!exception}}" {{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. +

    + + +

    The abort() method

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

    + + +

    Response

    + +

    The responseURL getter

    + +

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

    The status getter

    + +

    The status getter steps are to return +this's response's status. + + +

    The statusText getter

    + +

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

    The getResponseHeader() method

    + +

    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
    +
    + + +

    The getAllResponseHeaders() method

    + +

    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
    +
    + + +

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

    The overrideMimeType() method

    + +
    +
    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!!exception}}" {{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!!exception}}" {{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. +

    + + +

    The responseType getter and setter

    + +
    +
    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!!exception}}" {{DOMException}} if state is + loading or done. + +

    When set: throws an "{{InvalidAccessError!!exception}}" {{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 {{XMLHttpRequest/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!!exception}}" {{DOMException}}. + +

    3. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

    4. Set this's response type to the given value. +

    + + +

    The response getter

    + +
    +
    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 {{Blob/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. +

    + + +

    The responseText getter

    + +
    +
    client . responseText +
    +

    Returns response as text. + +

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

    + + +

    The responseXML getter

    + +
    +
    client . responseXML +
    +

    Returns the response as document. + +

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

    + + +

    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 {{XMLHttpRequest/readyState}} attribute changes + value, except when it changes to UNSENT. +
    loadstart + {{ProgressEvent}} + The fetch initiates. +
    progress + {{ProgressEvent}} + Transmitting data. +
    abort + {{ProgressEvent}} + When the fetch has been aborted. For instance, by invoking the + {{XMLHttpRequest/abort()}} method. +
    error + {{ProgressEvent}} + The fetch failed. +
    load + {{ProgressEvent}} + The fetch succeeded. +
    timeout + {{ProgressEvent}} + The author specified timeout has passed before the fetch completed. +
    loadend + {{ProgressEvent}} + The fetch completed (success or failure). +
    + + +

    Interface {{FormData}}

    + +
    +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 (an +entry list). It is initially empty. + +

    This section used to define +entry, an entry's +name and +value, and the +create an entry algorithm. These definitions have been +moved to the HTML Standard. [[HTML]] + +

    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!!exception}}" + {{DOMException}}. + +

      3. Set this's entry list to list. +

      +
    + +

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

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

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

    + +

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

    + +

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

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

    Interface {{ProgressEvent}}

    + +
    +[Exposed=(Window,Worker)]
    +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. + +

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

    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 {{ProgressEvent/loaded}} +attribute initialized to transmitted, and if length is not 0, with the +{{ProgressEvent/lengthComputable}} attribute initialized to true and the {{ProgressEvent/total}} +attribute initialized to length. + + +

    Suggested names for events using the {{ProgressEvent}} interface

    + +

    This section is non-normative. + +

    The suggested {{Event/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. + + + + + + + + + + + +
    {{Event/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 {{Event/bubbles}} and {{Event/cancelable}} +attributes initialized to false, so it is suggested that for consistency all +events using the +{{ProgressEvent}} interface do the same. + + +

    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]] + + +

    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, +Chirag S Kumar, +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, +Rashika Jaggi, +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). diff --git a/xhr.bs b/xhr.bs index b7f5dfd..d7fbaff 100644 --- a/xhr.bs +++ b/xhr.bs @@ -3,7 +3,7 @@ Group: WHATWG H1: XMLHttpRequest Shortname: xhr Text Macro: TWITTER xhrstandard -Text Macro: LATESTRD 2021-08 +Text Macro: LATESTRD 2022-02 Abstract: The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server. Translation: ja https://triple-underscore.github.io/XHR-ja.html Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue From 6876cf5cd82b12007f816b865757c868360f5197 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Thu, 10 Mar 2022 11:33:30 +0100 Subject: [PATCH 10/32] Editorial: remove dependency on responsible document Helps with https://github.com/whatwg/html/pull/7694. --- xhr.bs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/xhr.bs b/xhr.bs index d7fbaff..2e81ddd 100644 --- a/xhr.bs +++ b/xhr.bs @@ -424,10 +424,9 @@ and 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!!exception}}" {{DOMException}}. +

    3. If this's relevant global object is a {{Window}} object and its + associated Document is not fully active, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}.

    4. If method is not a method, then throw a "{{SyntaxError!!exception}}" {{DOMException}}. @@ -438,8 +437,10 @@ method steps are:

    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. + this's relevant settings object's + API base URL and this's + relevant settings object's + API URL character encoding.

    7. If parsedURL is failure, then throw a "{{SyntaxError!!exception}}" {{DOMException}}. From fd116b8bf759887210c8237ac4aad8578a1ff0a3 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Fri, 11 Mar 2022 10:32:18 +0100 Subject: [PATCH 11/32] Editorial: consistify the current global object language --- xhr.bs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/xhr.bs b/xhr.bs index 2e81ddd..2910e66 100644 --- a/xhr.bs +++ b/xhr.bs @@ -406,15 +406,16 @@ the use-CORS-preflight flag to be set.) case-insensitive match for `CONNECT`, `TRACE`, or `TRACK`.

      Throws an "{{InvalidAccessError!!exception}}" {{DOMException}} if async is false, - current global object is a {{Window}} object, and the {{XMLHttpRequest/timeout!!attribute}} - attribute is not zero or the {{XMLHttpRequest/responseType}} attribute is not the empty string. + the current global object is a {{Window}} object, and the + {{XMLHttpRequest/timeout!!attribute}} attribute is not zero or the {{XMLHttpRequest/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 +async argument when the 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!!exception}}" {{DOMException}} when it occurs.

      The @@ -580,7 +581,7 @@ client.send(); send() method).

      When set: throws an "{{InvalidAccessError!!exception}}" {{DOMException}} if the - synchronous flag is set and current global object is a {{Window}} object. + synchronous flag is set and the current global object is a {{Window}} object.

      The timeout getter steps are to return @@ -1385,6 +1386,7 @@ steps are:

      client . responseType [ = value ]

      Returns the response type. +

      Can be set to change the response type. Values are: the empty string (default), "arraybuffer", @@ -1392,15 +1394,15 @@ steps are: "document", "json", and "text". -

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

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

      When set: throws an "{{InvalidStateError!!exception}}" {{DOMException}} if state is loading or done.

      When set: throws an "{{InvalidAccessError!!exception}}" {{DOMException}} if the - synchronous flag is set and current global object is a {{Window}} object. + synchronous flag is set and the current global object is a {{Window}} object.

      The responseType getter steps are to return From 9d481f89437aae9048d83597cd06da5f3e02dec8 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Thu, 17 Mar 2022 18:58:50 +0200 Subject: [PATCH 12/32] Use fetch controller when terminating/aborting Closes #345. Co-authored-by: Anne van Kesteren --- xhr.bs | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/xhr.bs b/xhr.bs index 2910e66..565f587 100644 --- a/xhr.bs +++ b/xhr.bs @@ -240,6 +240,12 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {

      response object
      An object, failure, or null, initially null. +
      fetch controller +
      A fetch controller, initially a new fetch controller. + The send() method sets it to a useful + fetch controller, but for simplicity it always holds a + fetch controller. +
      override MIME type
      A MIME type or null, initially null. Can get a value when {{overrideMimeType()}} is invoked. @@ -281,9 +287,9 @@ registered whose type is one of 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. +

      If an {{XMLHttpRequest}} object is garbage collected while its connection is still open, the user +agent must terminate the {{XMLHttpRequest}} object's +fetch controller.

      Event handlers

      @@ -471,11 +477,10 @@ method steps are: the empty string, then throw an "{{InvalidAccessError!!exception}}" {{DOMException}}.
    8. -

      Terminate the ongoing fetch operated by the - {{XMLHttpRequest}} object. +

      Terminate this's + fetch controller. -

      A fetch can be - ongoing at this point. +

      A fetch can be ongoing at this point.

    9. Set variables associated with the object as follows: @@ -896,7 +901,8 @@ return this's cross-origin credentials. processBodyError, and this's relevant global object.

    -
  • Fetch req with +

  • Set this's fetch controller to the result of + fetching req with processRequestBodyChunkLength set to processRequestBodyChunkLength, processRequestEndOfBody set to processRequestEndOfBody, and processResponse set to @@ -914,7 +920,8 @@ return this's cross-origin credentials. now.

  • If req's done flag is unset, then set this's - timed out flag and terminate fetching. + timed out flag and terminate this's + fetch controller. @@ -938,9 +945,10 @@ return this's cross-origin credentials.

  • Set processedResponse to true. -

  • Fetch req with processResponseConsumeBody - set to processResponseConsumeBody and useParallelQueue set to - true. +

  • Set this's fetch controller to the result of + fetching req with + processResponseConsumeBody set to processResponseConsumeBody + and useParallelQueue set to true.

  • Let now be the present time. @@ -950,7 +958,7 @@ return this's cross-origin credentials. now.

  • If processedResponse is false, then set this's timed out flag and - terminate fetching. + terminate this's fetch controller.

  • Run handle response end-of-body for this. @@ -1073,7 +1081,8 @@ return this's cross-origin credentials.

    The abort() method steps are:

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

    2. Abort this's + fetch controller.

    3. If this's state is opened with this's send() flag set, headers received, or loading, then run the @@ -1953,6 +1962,7 @@ Martin Hassman, Mike Pennisi, Mohamed Zergaoui, Ms2ger, +Noam Rosenthal, Odin Hørthe Omdal, Olli Pettay, Pawel Glowacki, From f1b05ebf4e2e70fa06f9f569d545fd6eec9d71d8 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 11 May 2022 14:38:43 +0200 Subject: [PATCH 13/32] Editorial: use fetch's new "body with type" --- xhr.bs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/xhr.bs b/xhr.bs index 565f587..3de11f2 100644 --- a/xhr.bs +++ b/xhr.bs @@ -685,8 +685,20 @@ return this's cross-origin credentials. body, serialized, converted, and UTF-8 encoded. -

    4. Otherwise, set this's request body and extractedContentType to - the result of safely extracting body. +

    5. +

      Otherwise: + +

        +
      1. Let bodyWithType be the result of + safely extracting body. + +

      2. Set this's request body to bodyWithType's + body. + +

      3. Set extractedContentType to bodyWithType's + type. +

      +
    6. Let originalAuthorContentType be the result of getting `Content-Type` from this's author request headers. From 30dd5046c97a3fdc5af4d5b53269fa92b5bed290 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Mon, 15 Aug 2022 10:39:30 +0300 Subject: [PATCH 14/32] Editorial: refactor for reporting timing from Fetch Depends on https://github.com/whatwg/fetch/pull/1413. --- xhr.bs | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/xhr.bs b/xhr.bs index 3de11f2..04516f1 100644 --- a/xhr.bs +++ b/xhr.bs @@ -781,6 +781,8 @@ return this's cross-origin credentials. otherwise "same-origin".

      use-URL-credentials flag
      Set if this's request URL includes credentials. +
      initiator type +
      "xmlhttprequest".
    7. Unset this's upload complete flag. @@ -972,14 +974,13 @@ return this's cross-origin credentials.

    8. If processedResponse is false, then set this's timed out flag and terminate this's fetch controller. +

    9. Report timing for this's + fetch controller given the current global object. +

    10. Run handle response end-of-body for this.

    -

    To report timing for an {{XMLHttpRequest}} object xhr, -finalize and report timing with xhr's response, -xhr's relevant global object, and "xmlhttprequest". -

    To handle response end-of-body for an {{XMLHttpRequest}} object xhr, run these steps: @@ -989,8 +990,6 @@ return this's cross-origin credentials.

  • If xhr's response is a network error, then return. -

  • Report timing for xhr. -

  • Let transmitted be xhr's received bytes's length. @@ -1029,16 +1028,9 @@ return this's cross-origin credentials. aborted flag is set, run the request error steps for xhr, abort, and "{{AbortError!!exception}}" {{DOMException}}. -

  • -

    Otherwise, if xhr's response is a - network error, then: - -

      -
    1. Report timing for xhr. - -

    2. Run the request error steps for xhr, - error, and "{{NetworkError!!exception}}" {{DOMException}}. -

    +
  • Otherwise, if xhr's response is a + network error, then run the request error steps for xhr, + error, and "{{NetworkError!!exception}}" {{DOMException}}.

    The request error steps for an {{XMLHttpRequest}} object xhr, From fb328afbf9f0f913c0399bbff90367f2ba2bad69 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Mon, 15 Aug 2022 16:41:20 +0900 Subject: [PATCH 15/32] Review Draft Publication: August 2022 --- review-drafts/2022-08.bs | 2017 ++++++++++++++++++++++++++++++++++++++ xhr.bs | 2 +- 2 files changed, 2018 insertions(+), 1 deletion(-) create mode 100644 review-drafts/2022-08.bs diff --git a/review-drafts/2022-08.bs b/review-drafts/2022-08.bs new file mode 100644 index 0000000..bfd2056 --- /dev/null +++ b/review-drafts/2022-08.bs @@ -0,0 +1,2017 @@ +

    + +
    +urlPrefix: https://w3c.github.io/DOM-Parsing/; spec: dom-parsing
    +    type: dfn; text: fragment serializing algorithm; url: dfn-fragment-serializing-algorithm
    +
    + + + +

    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();
    +}
    +
    + + +

    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: + +

    + + + +

    Terminology

    + +

    This specification depends on the Infra Standard. [[!INFRA]] + +

    This specification uses terminology from DOM, DOM Parsing and Serialization, Encoding, +Fetch, File API, HTML, URL, Web IDL, and XML. + +[[!DOM]] +[[!DOM-PARSING]] +[[!ENCODING]] +[[!FETCH]] +[[!FILEAPI]] +[[!HTML]] +[[!URL]] +[[!WEBIDL]] +[[!XML]] [[!XML-NAMES]] + + + +

    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. + +
    fetch controller +
    A fetch controller, initially a new fetch controller. + The send() method sets it to a useful + fetch controller, but for simplicity it always holds a + fetch controller. + +
    override MIME type +
    A MIME type or null, initially null. Can get a value when + {{overrideMimeType()}} is invoked. +
    + + +

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

    + + +

    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 {{XMLHttpRequest}} object's +fetch controller. + + +

    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 +
    + + +

    States

    + +
    +
    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). +
    + + +

    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.) + + +

    The open() method

    + +
    +
    client . open(method, url [, async = true [, username = null [, password = null]]]) + +
    +

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

    Throws a "{{SyntaxError!!exception}}" {{DOMException}} if either method is not a + valid method or url cannot be parsed. + +

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

    Throws an "{{InvalidAccessError!!exception}}" {{DOMException}} if async is false, + the current global object is a {{Window}} object, and the + {{XMLHttpRequest/timeout!!attribute}} attribute is not zero or the {{XMLHttpRequest/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 the 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!!exception}}" {{DOMException}} when it occurs. + +

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

      +
    1. If this's relevant global object is a {{Window}} object and its + associated Document is not fully active, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

    2. If method is not a method, then throw a + "{{SyntaxError!!exception}}" {{DOMException}}. + +

    3. If method is a forbidden method, then throw a + "{{SecurityError!!exception}}" {{DOMException}}. + +

    4. Normalize method. + +

    5. Let parsedURL be the result of parsing url with + this's relevant settings object's + API base URL and this's + relevant settings object's + API URL character encoding. + +

    6. If parsedURL is failure, then throw a "{{SyntaxError!!exception}}" + {{DOMException}}. + +

    7. +

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

    8. +

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

      + +
    9. 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!!exception}}" {{DOMException}}. + +

    10. +

      Terminate this's + fetch controller. + +

      A fetch can be ongoing at this point. + +

    11. +

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

    12. +

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

    The setRequestHeader() method

    + +
    +
    client . setRequestHeader(name, value) + +
    +

    Combines a header in author request headers. + +

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if either state is not + opened or the send() flag is set. + +

    Throws a "{{SyntaxError!!exception}}" {{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!!exception}}" {{DOMException}}. + +

    2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

    3. Normalize value. + +

    4. +

      If name is not a header name or value is not a + header value, then throw a "{{SyntaxError!!exception}}" {{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
    +
    + + +

    The timeout getter and setter

    + +
    +
    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!!exception}}" {{DOMException}} will be thrown otherwise (for the + send() method). + +

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

    + +

    The timeout getter steps are to return +this's timeout. + +

    The {{XMLHttpRequest/timeout!!attribute}} setter steps are: + +

      +
    1. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

    2. Set this's timeout to the given value. +

    + +

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

    The withCredentials getter and setter

    + +
    +
    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!!exception}}" {{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 {{XMLHttpRequest/withCredentials}} setter steps are: + +

      +
    1. If this's state is not unsent or opened, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

    2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

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

    + + +

    The upload getter

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

    The send() method

    + +
    +
    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!!exception}}" {{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!!exception}}" {{DOMException}}. + +

    2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{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: + +

          +
        1. Let bodyWithType be the result of + safely extracting body. + +

        2. Set this's request body to bodyWithType's + body. + +

        3. Set extractedContentType to bodyWithType's + type. +

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

      6. +

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

            +
          +
        + +
      7. +

        Otherwise: + +

          +
        1. If body is an HTML document, then 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. +
      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. +
      initiator type +
      "xmlhttprequest". +
      + +
    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. Let requestBodyTransmitted be 0. + +

      3. Let requestBodyLength be req's body's + length, if req's body is non-null; otherwise 0. + +

      4. Assert: requestBodyLength is an integer. + +

      5. 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 + requestBodyTransmitted and requestBodyLength. + +

      6. If this's state is not opened or this's + send() flag is unset, then return. + +

      7. +

        Let processRequestBodyChunkLength, given a bytesLength, be these steps: + +

          +
        1. Increase requestBodyTransmitted by bytesLength. + +

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

        3. If this's upload listener flag is set, then fire a progress event + named progress at this's upload object with + requestBodyTransmitted and requestBodyLength. + +

        + +

        These steps are only invoked when new bytes are transmitted. + +

      8. +

        Let processRequestEndOfBody be these steps: + +

          +
        1. Set this's upload complete flag. + +

        2. If this's upload listener flag is unset, then return. + +

        3. Fire a progress event named progress at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

        4. Fire a progress event named load at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

        5. Fire a progress event named loadend at this's + upload object with requestBodyTransmitted and requestBodyLength. +

        + + +
      9. +

        Let processResponse, given a response, be these steps: + +

          +
        1. Set this's response to response. + +

        2. Handle errors for this. + +

        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 return. + +

        8. Let length be the result of extracting a length from + this's response's header list. + +

        9. If length is not an integer, then set it to 0. + +

        10. +

          Let processBodyChunk given bytes be these steps: + +

            +
          1. Append bytes to this's received bytes. + +

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

          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 received bytes's length and + length. +

          + +
        11. Let processEndOfBody be this step: run handle response end-of-body for + this. + +

        12. +

          Let processBodyError be these steps: + +

            +
          1. Set this's response to a network error. + +

          2. Run handle errors for this. +

          + +
        13. Incrementally read this's response's + body, given processBodyChunk, processEndOfBody, + processBodyError, and this's relevant global object. +

        + +
      10. Set this's fetch controller to the result of + fetching req with + processRequestBodyChunkLength set to + processRequestBodyChunkLength, processRequestEndOfBody set to + processRequestEndOfBody, and processResponse set to + processResponse. + +

      11. Let now be the present time. + + +

      12. +

        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 + now. + +

        2. If req's done flag is unset, then set this's + timed out flag and terminate this's + fetch controller. +

        +
      + +
    12. +

      Otherwise, if this's synchronous flag is set: + +

        +
      1. Let processedResponse be false. + +

      2. +

        Let processResponseConsumeBody, given a response and + nullOrFailureOrBytes, be these steps: + +

          +
        1. If nullOrFailureOrBytes is not failure, then set this's + response to response. + +

        2. If nullOrFailureOrBytes is a byte sequence, then append + nullOrFailureOrBytes to this's received bytes. + +

        3. Set processedResponse to true. +

        + +
      3. Set this's fetch controller to the result of + fetching req with + processResponseConsumeBody set to processResponseConsumeBody + and useParallelQueue set to true. + +

      4. Let now be the present time. + + +

      5. Pause until either processedResponse is true or this's + timeout is not 0 and this's timeout milliseconds have passed since + now. + +

      6. If processedResponse is false, then set this's timed out flag and + terminate this's fetch controller. + +

      7. Report timing for this's + fetch controller given the current global object. + +

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

      +
    + +

    To handle response end-of-body for an +{{XMLHttpRequest}} object xhr, run these steps: + +

      +
    1. Handle errors for xhr. + +

    2. If xhr's response is a network error, then + return. + +

    3. Let transmitted be xhr's received bytes's + length. + +

    4. Let length be the result of extracting a length from + this's response's header list. + +

    5. If length is not an integer, then set it to 0. + +

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

    7. Set xhr's state to done. + +

    8. Unset xhr's send() flag. + +

    9. Fire an event named readystatechange at xhr. + +

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

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

    + +

    To handle errors for an {{XMLHttpRequest}} object xhr, 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!!exception}}" + {{DOMException}}. + +

    3. Otherwise, if xhr's response's + aborted flag is set, run the request error steps for xhr, + abort, and "{{AbortError!!exception}}" {{DOMException}}. + +

    4. Otherwise, if xhr's response is a + network error, then run the request error steps for xhr, + error, and "{{NetworkError!!exception}}" {{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. +

    + + +

    The abort() method

    + +
    +
    client . abort() +
    Cancels any network activity. +
    + +

    The abort() method steps are: + +

      +
    1. Abort this's + fetch controller. + +

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

    + + +

    Response

    + +

    The responseURL getter

    + +

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

    The status getter

    + +

    The status getter steps are to return +this's response's status. + + +

    The statusText getter

    + +

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

    The getResponseHeader() method

    + +

    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
    +
    + + +

    The getAllResponseHeaders() method

    + +

    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
    +
    + + +

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

    The overrideMimeType() method

    + +
    +
    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!!exception}}" {{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!!exception}}" {{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. +

    + + +

    The responseType getter and setter

    + +
    +
    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 the current global object is + not a {{Window}} object. + +

    When set: throws an "{{InvalidStateError!!exception}}" {{DOMException}} if state is + loading or done. + +

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

    + +

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

    The {{XMLHttpRequest/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!!exception}}" {{DOMException}}. + +

    3. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

    4. Set this's response type to the given value. +

    + + +

    The response getter

    + +
    +
    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 {{Blob/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. +

    + + +

    The responseText getter

    + +
    +
    client . responseText +
    +

    Returns response as text. + +

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

    + + +

    The responseXML getter

    + +
    +
    client . responseXML +
    +

    Returns the response as document. + +

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

    + + +

    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 {{XMLHttpRequest/readyState}} attribute changes + value, except when it changes to UNSENT. +
    loadstart + {{ProgressEvent}} + The fetch initiates. +
    progress + {{ProgressEvent}} + Transmitting data. +
    abort + {{ProgressEvent}} + When the fetch has been aborted. For instance, by invoking the + {{XMLHttpRequest/abort()}} method. +
    error + {{ProgressEvent}} + The fetch failed. +
    load + {{ProgressEvent}} + The fetch succeeded. +
    timeout + {{ProgressEvent}} + The author specified timeout has passed before the fetch completed. +
    loadend + {{ProgressEvent}} + The fetch completed (success or failure). +
    + + +

    Interface {{FormData}}

    + +
    +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 (an +entry list). It is initially empty. + +

    This section used to define +entry, an entry's +name and +value, and the +create an entry algorithm. These definitions have been +moved to the HTML Standard. [[HTML]] + +

    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!!exception}}" + {{DOMException}}. + +

      3. Set this's entry list to list. +

      +
    + +

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

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

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

    + +

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

    + +

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

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

    Interface {{ProgressEvent}}

    + +
    +[Exposed=(Window,Worker)]
    +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. + +

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

    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 {{ProgressEvent/loaded}} +attribute initialized to transmitted, and if length is not 0, with the +{{ProgressEvent/lengthComputable}} attribute initialized to true and the {{ProgressEvent/total}} +attribute initialized to length. + + +

    Suggested names for events using the {{ProgressEvent}} interface

    + +

    This section is non-normative. + +

    The suggested {{Event/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. + + + + + + + + + + + +
    {{Event/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 {{Event/bubbles}} and {{Event/cancelable}} +attributes initialized to false, so it is suggested that for consistency all +events using the +{{ProgressEvent}} interface do the same. + + +

    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]] + + +

    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, +Chirag S Kumar, +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, +Noam Rosenthal, +Odin Hørthe Omdal, +Olli Pettay, +Pawel Glowacki, +Peter Michaux, +Philip Jägenstedt, +Philip Taylor, +Rashika Jaggi, +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). diff --git a/xhr.bs b/xhr.bs index 04516f1..3905626 100644 --- a/xhr.bs +++ b/xhr.bs @@ -3,7 +3,7 @@ Group: WHATWG H1: XMLHttpRequest Shortname: xhr Text Macro: TWITTER xhrstandard -Text Macro: LATESTRD 2022-02 +Text Macro: LATESTRD 2022-08 Abstract: The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server. Translation: ja https://triple-underscore.github.io/XHR-ja.html Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue From 31c5cf6164b800d492d0059c2aa5da6a07b4e34a Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Wed, 31 Aug 2022 10:00:10 +0200 Subject: [PATCH 16/32] Editorial: remove mention of internal field in non-normative text Closes #354. --- xhr.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xhr.bs b/xhr.bs index 3905626..e3a79e6 100644 --- a/xhr.bs +++ b/xhr.bs @@ -522,7 +522,7 @@ the editing software used to write the XMLHttpRequest Standard.

    client . setRequestHeader(name, value)
    -

    Combines a header in author request headers. +

    Appends a value to an existing request header or adds a new request header.

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if either state is not opened or the send() flag is set. From 112c3bb5a64579f9cb52a22b12ba1f8d9058f32e Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Mon, 17 Oct 2022 11:29:10 +0200 Subject: [PATCH 17/32] Meta: update repository files See https://github.com/whatwg/spec-factory for details. --- .github/workflows/build.yml | 6 +++--- .gitignore | 1 - Makefile | 6 +----- PULL_REQUEST_TEMPLATE.md | 7 ++++--- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 29d0c65..445136a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,13 +11,13 @@ jobs: name: Build runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 2 # Note: `python` will also be this version, which various scripts depend on. - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v3 with: - python-version: 3.8 + python-version: "3.10" # Note: `make deploy` will do a deploy dry run on PRs. - run: make deploy env: diff --git a/.gitignore b/.gitignore index 2980af4..70521ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ /xhr.spec.whatwg.org/ /deploy.sh /xhr.html -/review.sh diff --git a/Makefile b/Makefile index 74f4c2d..ebdb132 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ SHELL=/bin/bash -o pipefail -.PHONY: local remote deploy review +.PHONY: local remote deploy remote: xhr.bs @ (HTTP_STATUS=$$(curl https://api.csswg.org/bikeshed/ \ @@ -21,7 +21,3 @@ local: xhr.bs deploy: xhr.bs curl --remote-name --fail https://resources.whatwg.org/build/deploy.sh bash ./deploy.sh - -review: xhr.bs - curl --remote-name --fail https://resources.whatwg.org/build/review.sh - bash ./review.sh diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index cf29d04..c5c76a9 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -8,8 +8,9 @@ Thank you for contributing to the XMLHttpRequest Standard! Please describe the c - [ ] [Tests](https://github.com/web-platform-tests/wpt) are written and can be reviewed and commented upon at: * … - [ ] [Implementation bugs](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) are filed: - * Chrome: … - * Firefox: … - * Safari: … + * Chromium: … + * Gecko: … + * WebKit: … +- [ ] [MDN issue](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) is filed: … (See [WHATWG Working Mode: Changes](https://whatwg.org/working-mode#changes) for more details.) From 545cdd5ce9560c08a23245eb8486c48b40dedbae Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Wed, 26 Oct 2022 15:02:09 +0200 Subject: [PATCH 18/32] Meta: my employer changed --- xhr.bs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/xhr.bs b/xhr.bs index e3a79e6..dfcc3cd 100644 --- a/xhr.bs +++ b/xhr.bs @@ -2009,7 +2009,5 @@ the HTML Standard (then Web Applications 1.0). [[!HTML]] {{ProgressEvent}} class as part of the SVG Micro DOM. -

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

    This standard is written by Anne van Kesteren +(Apple, annevk@annevk.nl). From 494431ae9c8e7053fb27028b9f55b5c0c9ff8eca Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Mon, 21 Nov 2022 13:40:25 +0100 Subject: [PATCH 19/32] Align with Fetch's forbidden request-header refactor Fetch PR: https://github.com/whatwg/fetch/pull/1541. --- xhr.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xhr.bs b/xhr.bs index dfcc3cd..adf852d 100644 --- a/xhr.bs +++ b/xhr.bs @@ -550,7 +550,7 @@ method must run these steps:

    An empty byte sequence represents an empty header value. -

  • If name is a forbidden header name, then return. +

  • If (name, value) is a forbidden request-header, then return.

  • Combine (name, value) in this's author request headers. From 1c2d7f2a3bdbf06b53a40d5141a4e6484d25f791 Mon Sep 17 00:00:00 2001 From: Jon Jensen Date: Fri, 27 Jan 2023 00:02:40 -0700 Subject: [PATCH 20/32] Add optional submitter argument to FormData constructor Tests: https://github.com/web-platform-tests/wpt/pull/37895. Closes #262. --- xhr.bs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/xhr.bs b/xhr.bs index adf852d..721508c 100644 --- a/xhr.bs +++ b/xhr.bs @@ -9,6 +9,11 @@ Translation: ja https://triple-underscore.github.io/XHR-ja.html Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue + +

    +
     urlPrefix: https://w3c.github.io/DOM-Parsing/; spec: dom-parsing
         type: dfn; text: fragment serializing algorithm; url: dfn-fragment-serializing-algorithm
    @@ -1609,7 +1614,7 @@ typedef (File or USVString) FormDataEntryValue;
     
     [Exposed=(Window,Worker)]
     interface FormData {
    -  constructor(optional HTMLFormElement form);
    +  constructor(optional HTMLFormElement form, optional HTMLElement? submitter = null);
     
       undefined append(USVString name, USVString value);
       undefined append(USVString name, Blob blobValue, optional USVString filename);
    @@ -1635,7 +1640,7 @@ interface FormData {
     moved to the HTML Standard. [[HTML]]
     
     

    The -new FormData(form) +new FormData(form, submitter) constructor steps are:

      @@ -1643,8 +1648,19 @@ constructor steps are:

      If form is given, then:

        +
      1. +

        If submitter is non-null, then: + +

          +
        1. If submitter is not a submit button, then throw a + {{TypeError}}. + +

        2. If submitter's form owner is not form, then throw a + "{{NotFoundError!!exception}}" {{DOMException}}. +

        +
      2. Let list be the result of constructing the entry list for - form. + form and submitter.

      3. If list is null, then throw an "{{InvalidStateError!!exception}}" {{DOMException}}. From 1cccb46b45bfb714bac7658fb92b20022d77859d Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Mon, 20 Feb 2023 10:42:30 +0100 Subject: [PATCH 21/32] Review Draft Publication: February 2023 --- review-drafts/2023-02.bs | 2031 ++++++++++++++++++++++++++++++++++++++ xhr.bs | 2 +- 2 files changed, 2032 insertions(+), 1 deletion(-) create mode 100644 review-drafts/2023-02.bs diff --git a/review-drafts/2023-02.bs b/review-drafts/2023-02.bs new file mode 100644 index 0000000..320c199 --- /dev/null +++ b/review-drafts/2023-02.bs @@ -0,0 +1,2031 @@ +

        + + + + +
        +urlPrefix: https://w3c.github.io/DOM-Parsing/; spec: dom-parsing
        +    type: dfn; text: fragment serializing algorithm; url: dfn-fragment-serializing-algorithm
        +
        + + + +

        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();
        +}
        +
        + + +

        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: + +

        + + + +

        Terminology

        + +

        This specification depends on the Infra Standard. [[!INFRA]] + +

        This specification uses terminology from DOM, DOM Parsing and Serialization, Encoding, +Fetch, File API, HTML, URL, Web IDL, and XML. + +[[!DOM]] +[[!DOM-PARSING]] +[[!ENCODING]] +[[!FETCH]] +[[!FILEAPI]] +[[!HTML]] +[[!URL]] +[[!WEBIDL]] +[[!XML]] [[!XML-NAMES]] + + + +

        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. + +
        fetch controller +
        A fetch controller, initially a new fetch controller. + The send() method sets it to a useful + fetch controller, but for simplicity it always holds a + fetch controller. + +
        override MIME type +
        A MIME type or null, initially null. Can get a value when + {{overrideMimeType()}} is invoked. +
        + + +

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

        + + +

        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 {{XMLHttpRequest}} object's +fetch controller. + + +

        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 +
        + + +

        States

        + +
        +
        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). +
        + + +

        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.) + + +

        The open() method

        + +
        +
        client . open(method, url [, async = true [, username = null [, password = null]]]) + +
        +

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

        Throws a "{{SyntaxError!!exception}}" {{DOMException}} if either method is not a + valid method or url cannot be parsed. + +

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

        Throws an "{{InvalidAccessError!!exception}}" {{DOMException}} if async is false, + the current global object is a {{Window}} object, and the + {{XMLHttpRequest/timeout!!attribute}} attribute is not zero or the {{XMLHttpRequest/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 the 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!!exception}}" {{DOMException}} when it occurs. + +

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

          +
        1. If this's relevant global object is a {{Window}} object and its + associated Document is not fully active, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

        2. If method is not a method, then throw a + "{{SyntaxError!!exception}}" {{DOMException}}. + +

        3. If method is a forbidden method, then throw a + "{{SecurityError!!exception}}" {{DOMException}}. + +

        4. Normalize method. + +

        5. Let parsedURL be the result of parsing url with + this's relevant settings object's + API base URL and this's + relevant settings object's + API URL character encoding. + +

        6. If parsedURL is failure, then throw a "{{SyntaxError!!exception}}" + {{DOMException}}. + +

        7. +

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

        8. +

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

          + +
        9. 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!!exception}}" {{DOMException}}. + +

        10. +

          Terminate this's + fetch controller. + +

          A fetch can be ongoing at this point. + +

        11. +

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

        12. +

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

        The setRequestHeader() method

        + +
        +
        client . setRequestHeader(name, value) + +
        +

        Appends a value to an existing request header or adds a new request header. + +

        Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if either state is not + opened or the send() flag is set. + +

        Throws a "{{SyntaxError!!exception}}" {{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!!exception}}" {{DOMException}}. + +

        2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

        3. Normalize value. + +

        4. +

          If name is not a header name or value is not a + header value, then throw a "{{SyntaxError!!exception}}" {{DOMException}}. + +

          An empty byte sequence represents an empty header value. + +

        5. If (name, value) is a forbidden request-header, 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
        +
        + + +

        The timeout getter and setter

        + +
        +
        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!!exception}}" {{DOMException}} will be thrown otherwise (for the + send() method). + +

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

        + +

        The timeout getter steps are to return +this's timeout. + +

        The {{XMLHttpRequest/timeout!!attribute}} setter steps are: + +

          +
        1. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

        2. Set this's timeout to the given value. +

        + +

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

        The withCredentials getter and setter

        + +
        +
        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!!exception}}" {{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 {{XMLHttpRequest/withCredentials}} setter steps are: + +

          +
        1. If this's state is not unsent or opened, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

        2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

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

        + + +

        The upload getter

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

        The send() method

        + +
        +
        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!!exception}}" {{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!!exception}}" {{DOMException}}. + +

        2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{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: + +

              +
            1. Let bodyWithType be the result of + safely extracting body. + +

            2. Set this's request body to bodyWithType's + body. + +

            3. Set extractedContentType to bodyWithType's + type. +

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

          6. +

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

                +
              +
            + +
          7. +

            Otherwise: + +

              +
            1. If body is an HTML document, then 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. +
          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. +
          initiator type +
          "xmlhttprequest". +
          + +
        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. Let requestBodyTransmitted be 0. + +

          3. Let requestBodyLength be req's body's + length, if req's body is non-null; otherwise 0. + +

          4. Assert: requestBodyLength is an integer. + +

          5. 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 + requestBodyTransmitted and requestBodyLength. + +

          6. If this's state is not opened or this's + send() flag is unset, then return. + +

          7. +

            Let processRequestBodyChunkLength, given a bytesLength, be these steps: + +

              +
            1. Increase requestBodyTransmitted by bytesLength. + +

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

            3. If this's upload listener flag is set, then fire a progress event + named progress at this's upload object with + requestBodyTransmitted and requestBodyLength. + +

            + +

            These steps are only invoked when new bytes are transmitted. + +

          8. +

            Let processRequestEndOfBody be these steps: + +

              +
            1. Set this's upload complete flag. + +

            2. If this's upload listener flag is unset, then return. + +

            3. Fire a progress event named progress at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

            4. Fire a progress event named load at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

            5. Fire a progress event named loadend at this's + upload object with requestBodyTransmitted and requestBodyLength. +

            + + +
          9. +

            Let processResponse, given a response, be these steps: + +

              +
            1. Set this's response to response. + +

            2. Handle errors for this. + +

            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 return. + +

            8. Let length be the result of extracting a length from + this's response's header list. + +

            9. If length is not an integer, then set it to 0. + +

            10. +

              Let processBodyChunk given bytes be these steps: + +

                +
              1. Append bytes to this's received bytes. + +

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

              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 received bytes's length and + length. +

              + +
            11. Let processEndOfBody be this step: run handle response end-of-body for + this. + +

            12. +

              Let processBodyError be these steps: + +

                +
              1. Set this's response to a network error. + +

              2. Run handle errors for this. +

              + +
            13. Incrementally read this's response's + body, given processBodyChunk, processEndOfBody, + processBodyError, and this's relevant global object. +

            + +
          10. Set this's fetch controller to the result of + fetching req with + processRequestBodyChunkLength set to + processRequestBodyChunkLength, processRequestEndOfBody set to + processRequestEndOfBody, and processResponse set to + processResponse. + +

          11. Let now be the present time. + + +

          12. +

            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 + now. + +

            2. If req's done flag is unset, then set this's + timed out flag and terminate this's + fetch controller. +

            +
          + +
        12. +

          Otherwise, if this's synchronous flag is set: + +

            +
          1. Let processedResponse be false. + +

          2. +

            Let processResponseConsumeBody, given a response and + nullOrFailureOrBytes, be these steps: + +

              +
            1. If nullOrFailureOrBytes is not failure, then set this's + response to response. + +

            2. If nullOrFailureOrBytes is a byte sequence, then append + nullOrFailureOrBytes to this's received bytes. + +

            3. Set processedResponse to true. +

            + +
          3. Set this's fetch controller to the result of + fetching req with + processResponseConsumeBody set to processResponseConsumeBody + and useParallelQueue set to true. + +

          4. Let now be the present time. + + +

          5. Pause until either processedResponse is true or this's + timeout is not 0 and this's timeout milliseconds have passed since + now. + +

          6. If processedResponse is false, then set this's timed out flag and + terminate this's fetch controller. + +

          7. Report timing for this's + fetch controller given the current global object. + +

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

          +
        + +

        To handle response end-of-body for an +{{XMLHttpRequest}} object xhr, run these steps: + +

          +
        1. Handle errors for xhr. + +

        2. If xhr's response is a network error, then + return. + +

        3. Let transmitted be xhr's received bytes's + length. + +

        4. Let length be the result of extracting a length from + this's response's header list. + +

        5. If length is not an integer, then set it to 0. + +

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

        7. Set xhr's state to done. + +

        8. Unset xhr's send() flag. + +

        9. Fire an event named readystatechange at xhr. + +

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

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

        + +

        To handle errors for an {{XMLHttpRequest}} object xhr, 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!!exception}}" + {{DOMException}}. + +

        3. Otherwise, if xhr's response's + aborted flag is set, run the request error steps for xhr, + abort, and "{{AbortError!!exception}}" {{DOMException}}. + +

        4. Otherwise, if xhr's response is a + network error, then run the request error steps for xhr, + error, and "{{NetworkError!!exception}}" {{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. +

        + + +

        The abort() method

        + +
        +
        client . abort() +
        Cancels any network activity. +
        + +

        The abort() method steps are: + +

          +
        1. Abort this's + fetch controller. + +

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

        + + +

        Response

        + +

        The responseURL getter

        + +

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

        The status getter

        + +

        The status getter steps are to return +this's response's status. + + +

        The statusText getter

        + +

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

        The getResponseHeader() method

        + +

        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
        +
        + + +

        The getAllResponseHeaders() method

        + +

        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
        +
        + + +

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

        The overrideMimeType() method

        + +
        +
        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!!exception}}" {{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!!exception}}" {{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. +

        + + +

        The responseType getter and setter

        + +
        +
        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 the current global object is + not a {{Window}} object. + +

        When set: throws an "{{InvalidStateError!!exception}}" {{DOMException}} if state is + loading or done. + +

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

        + +

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

        The {{XMLHttpRequest/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!!exception}}" {{DOMException}}. + +

        3. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

        4. Set this's response type to the given value. +

        + + +

        The response getter

        + +
        +
        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 {{Blob/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. +

        + + +

        The responseText getter

        + +
        +
        client . responseText +
        +

        Returns response as text. + +

        Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

        + + +

        The responseXML getter

        + +
        +
        client . responseXML +
        +

        Returns the response as document. + +

        Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

        + + +

        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 {{XMLHttpRequest/readyState}} attribute changes + value, except when it changes to UNSENT. +
        loadstart + {{ProgressEvent}} + The fetch initiates. +
        progress + {{ProgressEvent}} + Transmitting data. +
        abort + {{ProgressEvent}} + When the fetch has been aborted. For instance, by invoking the + {{XMLHttpRequest/abort()}} method. +
        error + {{ProgressEvent}} + The fetch failed. +
        load + {{ProgressEvent}} + The fetch succeeded. +
        timeout + {{ProgressEvent}} + The author specified timeout has passed before the fetch completed. +
        loadend + {{ProgressEvent}} + The fetch completed (success or failure). +
        + + +

        Interface {{FormData}}

        + +
        +typedef (File or USVString) FormDataEntryValue;
        +
        +[Exposed=(Window,Worker)]
        +interface FormData {
        +  constructor(optional HTMLFormElement form, optional HTMLElement? submitter = null);
        +
        +  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 (an +entry list). It is initially empty. + +

        This section used to define +entry, an entry's +name and +value, and the +create an entry algorithm. These definitions have been +moved to the HTML Standard. [[HTML]] + +

        The +new FormData(form, submitter) +constructor steps are: + +

          +
        1. +

          If form is given, then: + +

            +
          1. +

            If submitter is non-null, then: + +

              +
            1. If submitter is not a submit button, then throw a + {{TypeError}}. + +

            2. If submitter's form owner is not form, then throw a + "{{NotFoundError!!exception}}" {{DOMException}}. +

            + +
          2. Let list be the result of constructing the entry list for + form and submitter. + +

          3. If list is null, then throw an "{{InvalidStateError!!exception}}" + {{DOMException}}. + +

          4. Set this's entry list to list. +

          +
        + +

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

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

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

        + +

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

        + +

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

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

        Interface {{ProgressEvent}}

        + +
        +[Exposed=(Window,Worker)]
        +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. + +

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

        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 {{ProgressEvent/loaded}} +attribute initialized to transmitted, and if length is not 0, with the +{{ProgressEvent/lengthComputable}} attribute initialized to true and the {{ProgressEvent/total}} +attribute initialized to length. + + +

        Suggested names for events using the {{ProgressEvent}} interface

        + +

        This section is non-normative. + +

        The suggested {{Event/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. + + + + + + + + + + + +
        {{Event/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 {{Event/bubbles}} and {{Event/cancelable}} +attributes initialized to false, so it is suggested that for consistency all +events using the +{{ProgressEvent}} interface do the same. + + +

        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]] + + +

        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, +Chirag S Kumar, +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, +Noam Rosenthal, +Odin Hørthe Omdal, +Olli Pettay, +Pawel Glowacki, +Peter Michaux, +Philip Jägenstedt, +Philip Taylor, +Rashika Jaggi, +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 +(Apple, annevk@annevk.nl). diff --git a/xhr.bs b/xhr.bs index 721508c..105ae72 100644 --- a/xhr.bs +++ b/xhr.bs @@ -3,7 +3,7 @@ Group: WHATWG H1: XMLHttpRequest Shortname: xhr Text Macro: TWITTER xhrstandard -Text Macro: LATESTRD 2022-08 +Text Macro: LATESTRD 2023-02 Abstract: The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server. Translation: ja https://triple-underscore.github.io/XHR-ja.html Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue From a5597b99b0b9a611afc8fd8d8ebb0329b3324c19 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Fri, 22 Sep 2023 10:46:21 +0200 Subject: [PATCH 22/32] Editorial: use HTML's encoding-parse a URL Closes #380. --- xhr.bs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/xhr.bs b/xhr.bs index 105ae72..ad0f95d 100644 --- a/xhr.bs +++ b/xhr.bs @@ -448,11 +448,9 @@ method steps are:

      4. Normalize method. -

      5. Let parsedURL be the result of parsing url with - this's relevant settings object's - API base URL and this's - relevant settings object's - API URL character encoding. +

      6. Let parsedURL be the result of + encoding-parsing a URL url, relative to this's + relevant settings object.

      7. If parsedURL is failure, then throw a "{{SyntaxError!!exception}}" {{DOMException}}. @@ -1333,7 +1331,7 @@ not be web compatible.

      8. Set document's encoding to charset. -

      9. Set document's content type to finalMIME. +

      10. Set document's content type to finalMIME.

      11. Set document's URL to xhr's response's URL. From a2c40a0be1af035c093b07026802d1a327a74091 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Wed, 27 Sep 2023 16:07:13 +0200 Subject: [PATCH 23/32] Meta: update repository files See https://github.com/whatwg/spec-factory for details. --- .github/ISSUE_TEMPLATE/0-new-issue.yml | 17 ++++ .github/ISSUE_TEMPLATE/1-new-feature.yml | 27 ++++++ .github/ISSUE_TEMPLATE/config.yml | 8 ++ .github/workflows/build.yml | 7 +- PULL_REQUEST_TEMPLATE.md | 5 +- README.md | 112 +++++++++++++++++++---- 6 files changed, 151 insertions(+), 25 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/0-new-issue.yml create mode 100644 .github/ISSUE_TEMPLATE/1-new-feature.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/0-new-issue.yml b/.github/ISSUE_TEMPLATE/0-new-issue.yml new file mode 100644 index 0000000..05d64ce --- /dev/null +++ b/.github/ISSUE_TEMPLATE/0-new-issue.yml @@ -0,0 +1,17 @@ +name: New issue +description: File a new issue against the XMLHttpRequest Standard. +body: + - type: markdown + attributes: + value: | + Before filling out this form, please familiarize yourself with the [Code of Conduct](https://whatwg.org/code-of-conduct). You might also find the [FAQ](https://whatwg.org/faq) and [Working Mode](https://whatwg.org/working-mode) useful. + + If at any point you have questions, please reach out to us on [Chat](https://whatwg.org/chat). + - type: textarea + attributes: + label: "What is the issue with the XMLHttpRequest Standard?" + validations: + required: true + - type: markdown + attributes: + value: "Thank you for taking the time to improve the XMLHttpRequest Standard!" diff --git a/.github/ISSUE_TEMPLATE/1-new-feature.yml b/.github/ISSUE_TEMPLATE/1-new-feature.yml new file mode 100644 index 0000000..92120a8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1-new-feature.yml @@ -0,0 +1,27 @@ +name: New feature +description: Request a new feature in the XMLHttpRequest Standard. +labels: ["addition/proposal", "needs implementer interest"] +body: + - type: markdown + attributes: + value: | + Before filling out this form, please familiarize yourself with the [Code of Conduct](https://whatwg.org/code-of-conduct), [FAQ](https://whatwg.org/faq), and [Working Mode](https://whatwg.org/working-mode). They help with setting expectations and making sure you know what is required. The FAQ ["How should I go about proposing new features to WHATWG standards?"](https://whatwg.org/faq#adding-new-features) is especially relevant. + + If at any point you have questions, please reach out to us on [Chat](https://whatwg.org/chat). + - type: textarea + attributes: + label: "What problem are you trying to solve?" + validations: + required: true + - type: textarea + attributes: + label: "What solutions exist today?" + - type: textarea + attributes: + label: "How would you solve it?" + - type: textarea + attributes: + label: "Anything else?" + - type: markdown + attributes: + value: "Thank you for taking the time to improve the XMLHttpRequest Standard!" diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..70e8d0d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Chat + url: https://whatwg.org/chat + about: Please do reach out with questions and feedback! + - name: Stack Overflow + url: https://stackoverflow.com/ + about: If you're having trouble building a web page, this is not the right repository. Consider asking your question on Stack Overflow instead. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 445136a..af3476e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,15 +9,14 @@ on: jobs: build: name: Build - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 with: fetch-depth: 2 - # Note: `python` will also be this version, which various scripts depend on. - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" # Note: `make deploy` will do a deploy dry run on PRs. - run: make deploy env: diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index c5c76a9..b546c09 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -1,16 +1,19 @@ - [ ] At least two implementers are interested (and none opposed): * … * … - [ ] [Tests](https://github.com/web-platform-tests/wpt) are written and can be reviewed and commented upon at: - * … + * … - [ ] [Implementation bugs](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) are filed: * Chromium: … * Gecko: … * WebKit: … - [ ] [MDN issue](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) is filed: … +- [ ] The top of this comment includes a [clear commit message](https://github.com/whatwg/meta/blob/main/COMMITTING.md) to use. (See [WHATWG Working Mode: Changes](https://whatwg.org/working-mode#changes) for more details.) diff --git a/README.md b/README.md index 85befbd..76d76ea 100644 --- a/README.md +++ b/README.md @@ -2,38 +2,110 @@ This repository hosts the [XMLHttpRequest Standard](https://xhr.spec.whatwg.org/ ## Code of conduct -We are committed to providing a friendly, safe, and welcoming environment for all. Please read and -respect the [WHATWG Code of Conduct](https://whatwg.org/code-of-conduct). +We are committed to providing a friendly, safe, and welcoming environment for all. Please read and respect the [Code of Conduct](https://whatwg.org/code-of-conduct). ## Contribution opportunities -We'd love your help fixing outstanding issues. Pull requests for typographical and grammar errors -are also most welcome. +Folks notice minor and larger issues with the XMLHttpRequest Standard all the time and we'd love your help fixing those. Pull requests for typographical and grammar errors are also most welcome. -We'd be happy to mentor you through this process. If you're interested and need help getting -started, leave a comment on the issue or ask around [on IRC](https://whatwg.org/irc). +Issues labeled ["good first issue"](https://github.com/whatwg/xhr/labels/good%20first%20issue) are a good place to get a taste for editing the XMLHttpRequest Standard. Note that we don't assign issues and there's no reason to ask for availability either, just provide a pull request. + +If you are thinking of suggesting a new feature, read through the [FAQ](https://whatwg.org/faq) and [Working Mode](https://whatwg.org/working-mode) documents to get yourself familiarized with the process. + +We'd be happy to help you with all of this [on Chat](https://whatwg.org/chat). ## Pull requests -In short, change `xhr.bs` and submit your patch, with a -[good commit message](https://github.com/whatwg/meta/blob/main/COMMITTING.md). Consider -reading through the [WHATWG FAQ](https://whatwg.org/faq) if you are new here. +In short, change `xhr.bs` and submit your patch, with a [good commit message](https://github.com/whatwg/meta/blob/main/COMMITTING.md). + +Please add your name to the Acknowledgments section in your first pull request, even for trivial fixes. The names are sorted lexicographically. + +To ensure your patch meets all the necessary requirements, please also see the [Contributor Guidelines](https://github.com/whatwg/meta/blob/main/CONTRIBUTING.md). Editors of the XMLHttpRequest Standard are expected to follow the [Maintainer Guidelines](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md). + +## Tests -Please add your name to the Acknowledgments section in your first pull request, even for trivial -fixes. The names are sorted lexicographically. +Tests are an essential part of the standardization process and will need to be created or adjusted as changes to the standard are made. Tests for the XMLHttpRequest Standard can be found in the `xhr/` directory of [`web-platform-tests/wpt`](https://github.com/web-platform-tests/wpt). + +A dashboard showing the tests running against browser engines can be seen at [wpt.fyi/results/xhr](https://wpt.fyi/results/xhr). ## Building "locally" -For quick local iteration, run `make`. To verify your changes locally, run `make deploy`. See more -in the -[WHATWG Contributor Guidelines](https://github.com/whatwg/meta/blob/main/CONTRIBUTING.md#building). +For quick local iteration, run `make`; this will use a web service to build the standard, so that you don't have to install anything. See more in the [Contributor Guidelines](https://github.com/whatwg/meta/blob/main/CONTRIBUTING.md#building). -## Merge policy +## Formatting -If you can commit to this repository, see the -[WHATWG Maintainer Guidelines](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md). +Use a column width of 100 characters. + +Do not use newlines inside "inline" elements, even if that means exceeding the column width requirement. +```html +

        The +remove(tokens…) +method, when invoked, must run these steps: +``` +is okay and + ```html +

        The remove(tokens…) method, when +invoked, must run these steps: +``` +is not. + +Using newlines between "inline" element tag names and their content is also forbidden. (This actually alters the content, by adding spaces.) That is +```html +token +``` +is fine and +```html +token + +``` +is not. + +An `

      12. ` element always has a `

        ` element inside it, unless it's a child of `

          `. + +If a "block" element contains a single "block" element, do not put it on a newline. + +Do not indent for anything except a new "block" element. For instance +```html +
        • For each token in tokens, in given order, that is not in + tokens, append token to tokens. +``` +is not indented, but +```html +

            +
          1. +

            For each token in tokens, run these substeps: + +

              +
            1. If token is the empty string, throw a {{SyntaxError}} exception. +``` +is. + +End tags may be included (if done consistently) and attributes may be quoted (using double quotes), though the prevalent theme is to omit end tags and not quote attributes (unless they contain a space). + +Place one newline between paragraphs (including list elements). Place three newlines before `

              `, and two newlines before other headings. This does not apply when a nested heading follows the parent heading. +```html +
                +
              • Do not place a newline above. + +

              • Place a newline above. +

              + +

              Place a newline above. + + +

              Place two newlines above.

              + +

              Placing one newline is OK here.

              -## Tests -Tests can be found in the `xhr/` directory of -[web-platform-tests/wpt](https://github.com/web-platform-tests/wpt). +

              Place two newlines above.

              +``` +Use camel-case for variable names and "spaced" names for definitions, algorithms, etc. +```html +

              A request has an associated +redirect mode,... +``` +```html +

              Let redirectMode be request's redirect mode. +``` From 813e3082adbd536e50105a5e8ca6621c71724bdd Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Wed, 24 Jan 2024 11:17:43 +0100 Subject: [PATCH 24/32] Meta: update repository files See https://github.com/whatwg/spec-factory for details. Also address a number of xref issues. Co-authored-by: Domenic Denicola --- .editorconfig | 3 +++ .github/workflows/build.yml | 4 ++++ Makefile | 2 +- xhr.bs | 35 ++++++++++++++++++----------------- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/.editorconfig b/.editorconfig index 625d610..df39c7c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,6 +12,9 @@ max_line_length = 100 [Makefile] indent_style = tab +[*.md] +max_line_length = off + [*.bs] indent_size = 1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index af3476e..66fe55b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,5 @@ name: Build + on: pull_request: branches: @@ -6,6 +7,8 @@ on: push: branches: - main + workflow_dispatch: + jobs: build: name: Build @@ -17,6 +20,7 @@ jobs: - uses: actions/setup-python@v4 with: python-version: "3.11" + - run: pip install bikeshed && bikeshed update # Note: `make deploy` will do a deploy dry run on PRs. - run: make deploy env: diff --git a/Makefile b/Makefile index ebdb132..2ff0ded 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ remote: xhr.bs ); local: xhr.bs - bikeshed spec xhr.bs xhr.html --md-Text-Macro="COMMIT-SHA LOCAL COPY" + bikeshed spec xhr.bs xhr.html --md-Text-Macro="COMMIT-SHA LOCAL-COPY" deploy: xhr.bs curl --remote-name --fail https://resources.whatwg.org/build/deploy.sh diff --git a/xhr.bs b/xhr.bs index ad0f95d..424be65 100644 --- a/xhr.bs +++ b/xhr.bs @@ -283,13 +283,13 @@ constructor steps are: 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. +{{XMLHttpRequest/readystatechange}}, +{{XMLHttpRequest/progress}}, +{{XMLHttpRequest/abort}}, +{{XMLHttpRequest/error}}, +{{XMLHttpRequest/load}}, +{{XMLHttpRequest/timeout!!event}}, and +{{XMLHttpRequest/loadend}}.

              If an {{XMLHttpRequest}} object is garbage collected while its connection is still open, the user @@ -313,25 +313,25 @@ from {{XMLHttpRequestEventTarget}} as attributes: onloadstart - loadstart + {{XMLHttpRequest/loadstart}} onprogress - progress + {{XMLHttpRequest/progress}} onabort - abort + {{XMLHttpRequest/abort}} onerror - error + {{XMLHttpRequest/error}} onload - load + {{XMLHttpRequest/load}} ontimeout - timeout + {{XMLHttpRequest/timeout!!event}} onloadend - loadend + {{XMLHttpRequest/loadend}}

              The following is the @@ -1029,11 +1029,12 @@ return this's cross-origin credentials.

            2. Otherwise, if xhr's response's aborted flag is set, run the request error steps for xhr, - abort, and "{{AbortError!!exception}}" {{DOMException}}. + abort, and "{{AbortError!!exception}}" + {{DOMException}}.

            3. Otherwise, if xhr's response is a network error, then run the request error steps for xhr, - error, and "{{NetworkError!!exception}}" {{DOMException}}. + {{XMLHttpRequest/error}}, and "{{NetworkError!!exception}}" {{DOMException}}.

            The request error steps for an {{XMLHttpRequest}} object xhr, @@ -1093,7 +1094,7 @@ return this's cross-origin credentials.

          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. + request error steps for this and abort.

          3. If this's state is done, then set this's state to From fdd619d0a13fe4d8af1c9ffdb6de24cb88c53cc0 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Mon, 19 Feb 2024 10:55:34 -0800 Subject: [PATCH 25/32] Review Draft Publication: February 2024 --- review-drafts/2024-02.bs | 2031 ++++++++++++++++++++++++++++++++++++++ xhr.bs | 3 +- 2 files changed, 2033 insertions(+), 1 deletion(-) create mode 100644 review-drafts/2024-02.bs diff --git a/review-drafts/2024-02.bs b/review-drafts/2024-02.bs new file mode 100644 index 0000000..957bd3d --- /dev/null +++ b/review-drafts/2024-02.bs @@ -0,0 +1,2031 @@ +

            + + + + +
            +urlPrefix: https://w3c.github.io/DOM-Parsing/; spec: dom-parsing
            +    type: dfn; text: fragment serializing algorithm; url: dfn-fragment-serializing-algorithm
            +
            + + + +

            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();
            +}
            +
            + + +

            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: + +

            + + + +

            Terminology

            + +

            This specification depends on the Infra Standard. [[!INFRA]] + +

            This specification uses terminology from DOM, DOM Parsing and Serialization, Encoding, +Fetch, File API, HTML, URL, Web IDL, and XML. + +[[!DOM]] +[[!DOM-PARSING]] +[[!ENCODING]] +[[!FETCH]] +[[!FILEAPI]] +[[!HTML]] +[[!URL]] +[[!WEBIDL]] +[[!XML]] [[!XML-NAMES]] + + + +

            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. + +
            fetch controller +
            A fetch controller, initially a new fetch controller. + The send() method sets it to a useful + fetch controller, but for simplicity it always holds a + fetch controller. + +
            override MIME type +
            A MIME type or null, initially null. Can get a value when + {{overrideMimeType()}} is invoked. +
            + + +

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

            + + +

            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 +{{XMLHttpRequest/readystatechange}}, +{{XMLHttpRequest/progress}}, +{{XMLHttpRequest/abort}}, +{{XMLHttpRequest/error}}, +{{XMLHttpRequest/load}}, +{{XMLHttpRequest/timeout!!event}}, and +{{XMLHttpRequest/loadend}}. + + +

            If an {{XMLHttpRequest}} object is garbage collected while its connection is still open, the user +agent must terminate the {{XMLHttpRequest}} object's +fetch controller. + + +

            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 + {{XMLHttpRequest/loadstart}} +
            onprogress + {{XMLHttpRequest/progress}} +
            onabort + {{XMLHttpRequest/abort}} +
            onerror + {{XMLHttpRequest/error}} +
            onload + {{XMLHttpRequest/load}} +
            ontimeout + {{XMLHttpRequest/timeout!!event}} +
            onloadend + {{XMLHttpRequest/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 +
            + + +

            States

            + +
            +
            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). +
            + + +

            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.) + + +

            The open() method

            + +
            +
            client . open(method, url [, async = true [, username = null [, password = null]]]) + +
            +

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

            Throws a "{{SyntaxError!!exception}}" {{DOMException}} if either method is not a + valid method or url cannot be parsed. + +

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

            Throws an "{{InvalidAccessError!!exception}}" {{DOMException}} if async is false, + the current global object is a {{Window}} object, and the + {{XMLHttpRequest/timeout!!attribute}} attribute is not zero or the {{XMLHttpRequest/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 the 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!!exception}}" {{DOMException}} when it occurs. + +

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

              +
            1. If this's relevant global object is a {{Window}} object and its + associated Document is not fully active, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

            2. If method is not a method, then throw a + "{{SyntaxError!!exception}}" {{DOMException}}. + +

            3. If method is a forbidden method, then throw a + "{{SecurityError!!exception}}" {{DOMException}}. + +

            4. Normalize method. + +

            5. Let parsedURL be the result of + encoding-parsing a URL url, relative to this's + relevant settings object. + +

            6. If parsedURL is failure, then throw a "{{SyntaxError!!exception}}" + {{DOMException}}. + +

            7. +

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

            8. +

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

              + +
            9. 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!!exception}}" {{DOMException}}. + +

            10. +

              Terminate this's + fetch controller. + +

              A fetch can be ongoing at this point. + +

            11. +

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

            12. +

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

            The setRequestHeader() method

            + +
            +
            client . setRequestHeader(name, value) + +
            +

            Appends a value to an existing request header or adds a new request header. + +

            Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if either state is not + opened or the send() flag is set. + +

            Throws a "{{SyntaxError!!exception}}" {{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!!exception}}" {{DOMException}}. + +

            2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

            3. Normalize value. + +

            4. +

              If name is not a header name or value is not a + header value, then throw a "{{SyntaxError!!exception}}" {{DOMException}}. + +

              An empty byte sequence represents an empty header value. + +

            5. If (name, value) is a forbidden request-header, 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
            +
            + + +

            The timeout getter and setter

            + +
            +
            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!!exception}}" {{DOMException}} will be thrown otherwise (for the + send() method). + +

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

            + +

            The timeout getter steps are to return +this's timeout. + +

            The {{XMLHttpRequest/timeout!!attribute}} setter steps are: + +

              +
            1. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

            2. Set this's timeout to the given value. +

            + +

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

            The withCredentials getter and setter

            + +
            +
            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!!exception}}" {{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 {{XMLHttpRequest/withCredentials}} setter steps are: + +

              +
            1. If this's state is not unsent or opened, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

            2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

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

            + + +

            The upload getter

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

            The send() method

            + +
            +
            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!!exception}}" {{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!!exception}}" {{DOMException}}. + +

            2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{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: + +

                  +
                1. Let bodyWithType be the result of + safely extracting body. + +

                2. Set this's request body to bodyWithType's + body. + +

                3. Set extractedContentType to bodyWithType's + type. +

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

              6. +

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

                    +
                  +
                + +
              7. +

                Otherwise: + +

                  +
                1. If body is an HTML document, then 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. +
              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. +
              initiator type +
              "xmlhttprequest". +
              + +
            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. Let requestBodyTransmitted be 0. + +

              3. Let requestBodyLength be req's body's + length, if req's body is non-null; otherwise 0. + +

              4. Assert: requestBodyLength is an integer. + +

              5. 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 + requestBodyTransmitted and requestBodyLength. + +

              6. If this's state is not opened or this's + send() flag is unset, then return. + +

              7. +

                Let processRequestBodyChunkLength, given a bytesLength, be these steps: + +

                  +
                1. Increase requestBodyTransmitted by bytesLength. + +

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

                3. If this's upload listener flag is set, then fire a progress event + named progress at this's upload object with + requestBodyTransmitted and requestBodyLength. + +

                + +

                These steps are only invoked when new bytes are transmitted. + +

              8. +

                Let processRequestEndOfBody be these steps: + +

                  +
                1. Set this's upload complete flag. + +

                2. If this's upload listener flag is unset, then return. + +

                3. Fire a progress event named progress at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

                4. Fire a progress event named load at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

                5. Fire a progress event named loadend at this's + upload object with requestBodyTransmitted and requestBodyLength. +

                + + +
              9. +

                Let processResponse, given a response, be these steps: + +

                  +
                1. Set this's response to response. + +

                2. Handle errors for this. + +

                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 return. + +

                8. Let length be the result of extracting a length from + this's response's header list. + +

                9. If length is not an integer, then set it to 0. + +

                10. +

                  Let processBodyChunk given bytes be these steps: + +

                    +
                  1. Append bytes to this's received bytes. + +

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

                  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 received bytes's length and + length. +

                  + +
                11. Let processEndOfBody be this step: run handle response end-of-body for + this. + +

                12. +

                  Let processBodyError be these steps: + +

                    +
                  1. Set this's response to a network error. + +

                  2. Run handle errors for this. +

                  + +
                13. Incrementally read this's response's + body, given processBodyChunk, processEndOfBody, + processBodyError, and this's relevant global object. +

                + +
              10. Set this's fetch controller to the result of + fetching req with + processRequestBodyChunkLength set to + processRequestBodyChunkLength, processRequestEndOfBody set to + processRequestEndOfBody, and processResponse set to + processResponse. + +

              11. Let now be the present time. + + +

              12. +

                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 + now. + +

                2. If req's done flag is unset, then set this's + timed out flag and terminate this's + fetch controller. +

                +
              + +
            12. +

              Otherwise, if this's synchronous flag is set: + +

                +
              1. Let processedResponse be false. + +

              2. +

                Let processResponseConsumeBody, given a response and + nullOrFailureOrBytes, be these steps: + +

                  +
                1. If nullOrFailureOrBytes is not failure, then set this's + response to response. + +

                2. If nullOrFailureOrBytes is a byte sequence, then append + nullOrFailureOrBytes to this's received bytes. + +

                3. Set processedResponse to true. +

                + +
              3. Set this's fetch controller to the result of + fetching req with + processResponseConsumeBody set to processResponseConsumeBody + and useParallelQueue set to true. + +

              4. Let now be the present time. + + +

              5. Pause until either processedResponse is true or this's + timeout is not 0 and this's timeout milliseconds have passed since + now. + +

              6. If processedResponse is false, then set this's timed out flag and + terminate this's fetch controller. + +

              7. Report timing for this's + fetch controller given the current global object. + +

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

              +
            + +

            To handle response end-of-body for an +{{XMLHttpRequest}} object xhr, run these steps: + +

              +
            1. Handle errors for xhr. + +

            2. If xhr's response is a network error, then + return. + +

            3. Let transmitted be xhr's received bytes's + length. + +

            4. Let length be the result of extracting a length from + this's response's header list. + +

            5. If length is not an integer, then set it to 0. + +

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

            7. Set xhr's state to done. + +

            8. Unset xhr's send() flag. + +

            9. Fire an event named readystatechange at xhr. + +

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

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

            + +

            To handle errors for an {{XMLHttpRequest}} object xhr, 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!!exception}}" + {{DOMException}}. + +

            3. Otherwise, if xhr's response's + aborted flag is set, run the request error steps for xhr, + abort, and "{{AbortError!!exception}}" + {{DOMException}}. + +

            4. Otherwise, if xhr's response is a + network error, then run the request error steps for xhr, + {{XMLHttpRequest/error}}, and "{{NetworkError!!exception}}" {{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. +

            + + +

            The abort() method

            + +
            +
            client . abort() +
            Cancels any network activity. +
            + +

            The abort() method steps are: + +

              +
            1. Abort this's + fetch controller. + +

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

            + + +

            Response

            + +

            The responseURL getter

            + +

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

            The status getter

            + +

            The status getter steps are to return +this's response's status. + + +

            The statusText getter

            + +

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

            The getResponseHeader() method

            + +

            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
            +
            + + +

            The getAllResponseHeaders() method

            + +

            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
            +
            + + +

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

            The overrideMimeType() method

            + +
            +
            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!!exception}}" {{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!!exception}}" {{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. +

            + + +

            The responseType getter and setter

            + +
            +
            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 the current global object is + not a {{Window}} object. + +

            When set: throws an "{{InvalidStateError!!exception}}" {{DOMException}} if state is + loading or done. + +

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

            + +

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

            The {{XMLHttpRequest/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!!exception}}" {{DOMException}}. + +

            3. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

            4. Set this's response type to the given value. +

            + + +

            The response getter

            + +
            +
            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 {{Blob/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. +

            + + +

            The responseText getter

            + +
            +
            client . responseText +
            +

            Returns response as text. + +

            Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

            + + +

            The responseXML getter

            + +
            +
            client . responseXML +
            +

            Returns the response as document. + +

            Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

            + + +

            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 {{XMLHttpRequest/readyState}} attribute changes + value, except when it changes to UNSENT. +
            loadstart + {{ProgressEvent}} + The fetch initiates. +
            progress + {{ProgressEvent}} + Transmitting data. +
            abort + {{ProgressEvent}} + When the fetch has been aborted. For instance, by invoking the + {{XMLHttpRequest/abort()}} method. +
            error + {{ProgressEvent}} + The fetch failed. +
            load + {{ProgressEvent}} + The fetch succeeded. +
            timeout + {{ProgressEvent}} + The author specified timeout has passed before the fetch completed. +
            loadend + {{ProgressEvent}} + The fetch completed (success or failure). +
            + + +

            Interface {{FormData}}

            + +
            +typedef (File or USVString) FormDataEntryValue;
            +
            +[Exposed=(Window,Worker)]
            +interface FormData {
            +  constructor(optional HTMLFormElement form, optional HTMLElement? submitter = null);
            +
            +  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 (an +entry list). It is initially empty. + +

            This section used to define +entry, an entry's +name and +value, and the +create an entry algorithm. These definitions have been +moved to the HTML Standard. [[HTML]] + +

            The +new FormData(form, submitter) +constructor steps are: + +

              +
            1. +

              If form is given, then: + +

                +
              1. +

                If submitter is non-null, then: + +

                  +
                1. If submitter is not a submit button, then throw a + {{TypeError}}. + +

                2. If submitter's form owner is not form, then throw a + "{{NotFoundError!!exception}}" {{DOMException}}. +

                + +
              2. Let list be the result of constructing the entry list for + form and submitter. + +

              3. If list is null, then throw an "{{InvalidStateError!!exception}}" + {{DOMException}}. + +

              4. Set this's entry list to list. +

              +
            + +

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

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

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

            + +

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

            + +

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

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

            Interface {{ProgressEvent}}

            + +
            +[Exposed=(Window,Worker)]
            +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. + +

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

            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 {{ProgressEvent/loaded}} +attribute initialized to transmitted, and if length is not 0, with the +{{ProgressEvent/lengthComputable}} attribute initialized to true and the {{ProgressEvent/total}} +attribute initialized to length. + + +

            Suggested names for events using the {{ProgressEvent}} interface

            + +

            This section is non-normative. + +

            The suggested {{Event/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. + + + + + + + + + + + +
            {{Event/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 {{Event/bubbles}} and {{Event/cancelable}} +attributes initialized to false, so it is suggested that for consistency all +events using the +{{ProgressEvent}} interface do the same. + + +

            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]] + + +

            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, +Chirag S Kumar, +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, +Noam Rosenthal, +Odin Hørthe Omdal, +Olli Pettay, +Pawel Glowacki, +Peter Michaux, +Philip Jägenstedt, +Philip Taylor, +Rashika Jaggi, +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 +(Apple, annevk@annevk.nl). diff --git a/xhr.bs b/xhr.bs index 424be65..f6bd6c1 100644 --- a/xhr.bs +++ b/xhr.bs @@ -3,7 +3,7 @@ Group: WHATWG H1: XMLHttpRequest Shortname: xhr Text Macro: TWITTER xhrstandard -Text Macro: LATESTRD 2023-02 +Text Macro: LATESTRD 2024-02 Abstract: The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server. Translation: ja https://triple-underscore.github.io/XHR-ja.html Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue @@ -12,6 +12,7 @@ Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dic

            
            From fd438ec818714db1fcbd79c2ce06132d9cc4a100 Mon Sep 17 00:00:00 2001
            From: Dominique Hazael-Massieux 
            Date: Thu, 6 Jun 2024 13:08:04 +0200
            Subject: [PATCH 26/32] Meta: adjust dfn-for of events on
             XMLHttpRequestEventTarget
            
            As discovered in https://github.com/w3c/webref/issues/1216#issuecomment-2068997553.
            ---
             xhr.bs | 42 +++++++++++++++++++++---------------------
             1 file changed, 21 insertions(+), 21 deletions(-)
            
            diff --git a/xhr.bs b/xhr.bs
            index f6bd6c1..ac25a35 100644
            --- a/xhr.bs
            +++ b/xhr.bs
            @@ -285,12 +285,12 @@ constructor steps are:
             event listeners
             registered whose type is one of
             {{XMLHttpRequest/readystatechange}},
            -{{XMLHttpRequest/progress}},
            -{{XMLHttpRequest/abort}},
            -{{XMLHttpRequest/error}},
            -{{XMLHttpRequest/load}},
            -{{XMLHttpRequest/timeout!!event}}, and
            -{{XMLHttpRequest/loadend}}.
            +{{XMLHttpRequestEventTarget/progress}},
            +{{XMLHttpRequestEventTarget/abort}},
            +{{XMLHttpRequestEventTarget/error}},
            +{{XMLHttpRequestEventTarget/load}},
            +{{XMLHttpRequestEventTarget/timeout!!event}}, and
            +{{XMLHttpRequestEventTarget/loadend}}.
             
             
             

            If an {{XMLHttpRequest}} object is garbage collected while its connection is still open, the user @@ -314,25 +314,25 @@ from {{XMLHttpRequestEventTarget}} as attributes: onloadstart - {{XMLHttpRequest/loadstart}} + {{XMLHttpRequestEventTarget/loadstart}} onprogress - {{XMLHttpRequest/progress}} + {{XMLHttpRequestEventTarget/progress}} onabort - {{XMLHttpRequest/abort}} + {{XMLHttpRequestEventTarget/abort}} onerror - {{XMLHttpRequest/error}} + {{XMLHttpRequestEventTarget/error}} onload - {{XMLHttpRequest/load}} + {{XMLHttpRequestEventTarget/load}} ontimeout - {{XMLHttpRequest/timeout!!event}} + {{XMLHttpRequestEventTarget/timeout!!event}} onloadend - {{XMLHttpRequest/loadend}} + {{XMLHttpRequestEventTarget/loadend}}

            The following is the @@ -1035,7 +1035,7 @@ return this's cross-origin credentials.

          4. Otherwise, if xhr's response is a network error, then run the request error steps for xhr, - {{XMLHttpRequest/error}}, and "{{NetworkError!!exception}}" {{DOMException}}. + {{XMLHttpRequestEventTarget/error}}, and "{{NetworkError!!exception}}" {{DOMException}}.

          The request error steps for an {{XMLHttpRequest}} object xhr, @@ -1576,32 +1576,32 @@ steps are: The {{XMLHttpRequest/readyState}} attribute changes value, except when it changes to UNSENT. - loadstart + loadstart {{ProgressEvent}} The fetch initiates. - progress + progress {{ProgressEvent}} Transmitting data. - abort + abort {{ProgressEvent}} When the fetch has been aborted. For instance, by invoking the {{XMLHttpRequest/abort()}} method. - error + error {{ProgressEvent}} The fetch failed. - load + load {{ProgressEvent}} The fetch succeeded. - timeout + timeout {{ProgressEvent}} The author specified timeout has passed before the fetch completed. - loadend + loadend {{ProgressEvent}} The fetch completed (success or failure). From f2f0397a0dc416f315ac8930960df5fafa634a4d Mon Sep 17 00:00:00 2001 From: Luke Warlow Date: Mon, 12 Aug 2024 14:13:04 +0100 Subject: [PATCH 27/32] Meta: update link for fragment serialization algorithm See also https://github.com/whatwg/html/pull/10497. --- xhr.bs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/xhr.bs b/xhr.bs index ac25a35..3d44b15 100644 --- a/xhr.bs +++ b/xhr.bs @@ -15,11 +15,6 @@ spec:webdriver-bidi; type:dfn; text:event spec:fetch; type:dfn; for:/; text:credentials

    -
    -urlPrefix: https://w3c.github.io/DOM-Parsing/; spec: dom-parsing
    -    type: dfn; text: fragment serializing algorithm; url: dfn-fragment-serializing-algorithm
    -
    -

    Introduction

    @@ -686,7 +681,7 @@ return this's cross-origin credentials.
  • Let extractedContentType be null.

  • If body is a {{Document}}, then set this's request body to - body, serialized, + body, serialized, converted, and UTF-8 encoded.

  • @@ -1030,7 +1025,7 @@ return this's cross-origin credentials.
  • Otherwise, if xhr's response's aborted flag is set, run the request error steps for xhr, - abort, and "{{AbortError!!exception}}" + abort, and "{{AbortError!!exception}}" {{DOMException}}.

  • Otherwise, if xhr's response is a @@ -1095,7 +1090,8 @@ return this's cross-origin credentials.

  • 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. + request error steps for this and + abort.

  • If this's state is done, then set this's state to From 150a3b8e67187401e265a03753841100c4b1fcb1 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 21 Jan 2025 14:21:37 +0900 Subject: [PATCH 28/32] Editorial: fix Bikeshed linking errors --- xhr.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xhr.bs b/xhr.bs index 3d44b15..7fea6a8 100644 --- a/xhr.bs +++ b/xhr.bs @@ -1305,7 +1305,7 @@ not be web compatible.

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

  • Let document be a - document that + 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. @@ -1316,8 +1316,8 @@ not be web compatible.

  • -

    Otherwise, let document be a document that represents the result of running - the XML parser with XML scripting support disabled on xhr's +

    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]] From 4a6401c65333d504235fee794f63ed1aa40a3b41 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 21 Jan 2025 11:25:14 +0900 Subject: [PATCH 29/32] Allow doubles for ProgressEvent's loaded and total This allows specifications to use ProgressEvents while not necessarily giving away the exact number of bytes, while maintaining a granularity greater than just 1 part in 100. See discussion in https://github.com/webmachinelearning/writing-assistance-apis/issues/15 for the concrete use case. --- xhr.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xhr.bs b/xhr.bs index 7fea6a8..ba4fc2a 100644 --- a/xhr.bs +++ b/xhr.bs @@ -1753,14 +1753,14 @@ 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; + readonly attribute double loaded; + readonly attribute double total; }; dictionary ProgressEventInit : EventInit { boolean lengthComputable = false; - unsigned long long loaded = 0; - unsigned long long total = 0; + double loaded = 0; + double total = 0; }; From f284317e1f2611b0f43fe3ce68cbf645f0b0d5b2 Mon Sep 17 00:00:00 2001 From: JinDX Date: Tue, 15 Jul 2025 02:34:58 +0800 Subject: [PATCH 30/32] Meta: link Simplified Chinese translation Fixes #398. --- xhr.bs | 1 + 1 file changed, 1 insertion(+) diff --git a/xhr.bs b/xhr.bs index ba4fc2a..f9b05c6 100644 --- a/xhr.bs +++ b/xhr.bs @@ -6,6 +6,7 @@ Text Macro: TWITTER xhrstandard Text Macro: LATESTRD 2024-02 Abstract: The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server. Translation: ja https://triple-underscore.github.io/XHR-ja.html +Translation: zh-Hans https://htmlspecs.com/xhr/ Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue From a1706909aefdfc3ba09a01f72a53e893289b3bfa Mon Sep 17 00:00:00 2001 From: JinDX Date: Tue, 12 Aug 2025 21:33:58 +0800 Subject: [PATCH 31/32] Meta: link Korean translation --- xhr.bs | 1 + 1 file changed, 1 insertion(+) diff --git a/xhr.bs b/xhr.bs index f9b05c6..0dc3c97 100644 --- a/xhr.bs +++ b/xhr.bs @@ -7,6 +7,7 @@ Text Macro: LATESTRD 2024-02 Abstract: The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server. Translation: ja https://triple-underscore.github.io/XHR-ja.html Translation: zh-Hans https://htmlspecs.com/xhr/ +Translation: ko https://ko.htmlspecs.com/xhr/ Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue From 84b66b3f3867a2b19e2c862251021a4bf7d8acb1 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Mon, 18 Aug 2025 08:57:37 +0200 Subject: [PATCH 32/32] Review Draft Publication: August 2025 Also integrate the latest spec-factory. --- .github/workflows/build.yml | 4 +- PULL_REQUEST_TEMPLATE.md | 4 +- review-drafts/2025-08.bs | 2029 +++++++++++++++++++++++++++++++++++ xhr.bs | 2 +- 4 files changed, 2035 insertions(+), 4 deletions(-) create mode 100644 review-drafts/2025-08.bs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 66fe55b..f10e74c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,10 +14,10 @@ jobs: name: Build runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 2 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" - run: pip install bikeshed && bikeshed update diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index b546c09..04633b6 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,8 @@ diff --git a/review-drafts/2025-08.bs b/review-drafts/2025-08.bs new file mode 100644 index 0000000..adadfc3 --- /dev/null +++ b/review-drafts/2025-08.bs @@ -0,0 +1,2029 @@ +

    + + + + + + +

    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();
    +}
    +
    + + +

    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: + +

    + + + +

    Terminology

    + +

    This specification depends on the Infra Standard. [[!INFRA]] + +

    This specification uses terminology from DOM, DOM Parsing and Serialization, Encoding, +Fetch, File API, HTML, URL, Web IDL, and XML. + +[[!DOM]] +[[!DOM-PARSING]] +[[!ENCODING]] +[[!FETCH]] +[[!FILEAPI]] +[[!HTML]] +[[!URL]] +[[!WEBIDL]] +[[!XML]] [[!XML-NAMES]] + + + +

    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. + +
    fetch controller +
    A fetch controller, initially a new fetch controller. + The send() method sets it to a useful + fetch controller, but for simplicity it always holds a + fetch controller. + +
    override MIME type +
    A MIME type or null, initially null. Can get a value when + {{overrideMimeType()}} is invoked. +
    + + +

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

    + + +

    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 +{{XMLHttpRequest/readystatechange}}, +{{XMLHttpRequestEventTarget/progress}}, +{{XMLHttpRequestEventTarget/abort}}, +{{XMLHttpRequestEventTarget/error}}, +{{XMLHttpRequestEventTarget/load}}, +{{XMLHttpRequestEventTarget/timeout!!event}}, and +{{XMLHttpRequestEventTarget/loadend}}. + + +

    If an {{XMLHttpRequest}} object is garbage collected while its connection is still open, the user +agent must terminate the {{XMLHttpRequest}} object's +fetch controller. + + +

    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 + {{XMLHttpRequestEventTarget/loadstart}} +
    onprogress + {{XMLHttpRequestEventTarget/progress}} +
    onabort + {{XMLHttpRequestEventTarget/abort}} +
    onerror + {{XMLHttpRequestEventTarget/error}} +
    onload + {{XMLHttpRequestEventTarget/load}} +
    ontimeout + {{XMLHttpRequestEventTarget/timeout!!event}} +
    onloadend + {{XMLHttpRequestEventTarget/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 +
    + + +

    States

    + +
    +
    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). +
    + + +

    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.) + + +

    The open() method

    + +
    +
    client . open(method, url [, async = true [, username = null [, password = null]]]) + +
    +

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

    Throws a "{{SyntaxError!!exception}}" {{DOMException}} if either method is not a + valid method or url cannot be parsed. + +

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

    Throws an "{{InvalidAccessError!!exception}}" {{DOMException}} if async is false, + the current global object is a {{Window}} object, and the + {{XMLHttpRequest/timeout!!attribute}} attribute is not zero or the {{XMLHttpRequest/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 the 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!!exception}}" {{DOMException}} when it occurs. + +

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

      +
    1. If this's relevant global object is a {{Window}} object and its + associated Document is not fully active, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

    2. If method is not a method, then throw a + "{{SyntaxError!!exception}}" {{DOMException}}. + +

    3. If method is a forbidden method, then throw a + "{{SecurityError!!exception}}" {{DOMException}}. + +

    4. Normalize method. + +

    5. Let parsedURL be the result of + encoding-parsing a URL url, relative to this's + relevant settings object. + +

    6. If parsedURL is failure, then throw a "{{SyntaxError!!exception}}" + {{DOMException}}. + +

    7. +

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

    8. +

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

      + +
    9. 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!!exception}}" {{DOMException}}. + +

    10. +

      Terminate this's + fetch controller. + +

      A fetch can be ongoing at this point. + +

    11. +

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

    12. +

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

    The setRequestHeader() method

    + +
    +
    client . setRequestHeader(name, value) + +
    +

    Appends a value to an existing request header or adds a new request header. + +

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if either state is not + opened or the send() flag is set. + +

    Throws a "{{SyntaxError!!exception}}" {{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!!exception}}" {{DOMException}}. + +

    2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

    3. Normalize value. + +

    4. +

      If name is not a header name or value is not a + header value, then throw a "{{SyntaxError!!exception}}" {{DOMException}}. + +

      An empty byte sequence represents an empty header value. + +

    5. If (name, value) is a forbidden request-header, 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
    +
    + + +

    The timeout getter and setter

    + +
    +
    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!!exception}}" {{DOMException}} will be thrown otherwise (for the + send() method). + +

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

    + +

    The timeout getter steps are to return +this's timeout. + +

    The {{XMLHttpRequest/timeout!!attribute}} setter steps are: + +

      +
    1. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

    2. Set this's timeout to the given value. +

    + +

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

    The withCredentials getter and setter

    + +
    +
    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!!exception}}" {{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 {{XMLHttpRequest/withCredentials}} setter steps are: + +

      +
    1. If this's state is not unsent or opened, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

    2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +

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

    + + +

    The upload getter

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

    The send() method

    + +
    +
    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!!exception}}" {{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!!exception}}" {{DOMException}}. + +

    2. If this's send() flag is set, then throw an + "{{InvalidStateError!!exception}}" {{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: + +

          +
        1. Let bodyWithType be the result of + safely extracting body. + +

        2. Set this's request body to bodyWithType's + body. + +

        3. Set extractedContentType to bodyWithType's + type. +

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

      6. +

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

            +
          +
        + +
      7. +

        Otherwise: + +

          +
        1. If body is an HTML document, then 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. +
      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. +
      initiator type +
      "xmlhttprequest". +
      + +
    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. Let requestBodyTransmitted be 0. + +

      3. Let requestBodyLength be req's body's + length, if req's body is non-null; otherwise 0. + +

      4. Assert: requestBodyLength is an integer. + +

      5. 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 + requestBodyTransmitted and requestBodyLength. + +

      6. If this's state is not opened or this's + send() flag is unset, then return. + +

      7. +

        Let processRequestBodyChunkLength, given a bytesLength, be these steps: + +

          +
        1. Increase requestBodyTransmitted by bytesLength. + +

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

        3. If this's upload listener flag is set, then fire a progress event + named progress at this's upload object with + requestBodyTransmitted and requestBodyLength. + +

        + +

        These steps are only invoked when new bytes are transmitted. + +

      8. +

        Let processRequestEndOfBody be these steps: + +

          +
        1. Set this's upload complete flag. + +

        2. If this's upload listener flag is unset, then return. + +

        3. Fire a progress event named progress at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

        4. Fire a progress event named load at this's + upload object with requestBodyTransmitted and requestBodyLength. + +

        5. Fire a progress event named loadend at this's + upload object with requestBodyTransmitted and requestBodyLength. +

        + + +
      9. +

        Let processResponse, given a response, be these steps: + +

          +
        1. Set this's response to response. + +

        2. Handle errors for this. + +

        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 return. + +

        8. Let length be the result of extracting a length from + this's response's header list. + +

        9. If length is not an integer, then set it to 0. + +

        10. +

          Let processBodyChunk given bytes be these steps: + +

            +
          1. Append bytes to this's received bytes. + +

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

          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 received bytes's length and + length. +

          + +
        11. Let processEndOfBody be this step: run handle response end-of-body for + this. + +

        12. +

          Let processBodyError be these steps: + +

            +
          1. Set this's response to a network error. + +

          2. Run handle errors for this. +

          + +
        13. Incrementally read this's response's + body, given processBodyChunk, processEndOfBody, + processBodyError, and this's relevant global object. +

        + +
      10. Set this's fetch controller to the result of + fetching req with + processRequestBodyChunkLength set to + processRequestBodyChunkLength, processRequestEndOfBody set to + processRequestEndOfBody, and processResponse set to + processResponse. + +

      11. Let now be the present time. + + +

      12. +

        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 + now. + +

        2. If req's done flag is unset, then set this's + timed out flag and terminate this's + fetch controller. +

        +
      + +
    12. +

      Otherwise, if this's synchronous flag is set: + +

        +
      1. Let processedResponse be false. + +

      2. +

        Let processResponseConsumeBody, given a response and + nullOrFailureOrBytes, be these steps: + +

          +
        1. If nullOrFailureOrBytes is not failure, then set this's + response to response. + +

        2. If nullOrFailureOrBytes is a byte sequence, then append + nullOrFailureOrBytes to this's received bytes. + +

        3. Set processedResponse to true. +

        + +
      3. Set this's fetch controller to the result of + fetching req with + processResponseConsumeBody set to processResponseConsumeBody + and useParallelQueue set to true. + +

      4. Let now be the present time. + + +

      5. Pause until either processedResponse is true or this's + timeout is not 0 and this's timeout milliseconds have passed since + now. + +

      6. If processedResponse is false, then set this's timed out flag and + terminate this's fetch controller. + +

      7. Report timing for this's + fetch controller given the current global object. + +

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

      +
    + +

    To handle response end-of-body for an +{{XMLHttpRequest}} object xhr, run these steps: + +

      +
    1. Handle errors for xhr. + +

    2. If xhr's response is a network error, then + return. + +

    3. Let transmitted be xhr's received bytes's + length. + +

    4. Let length be the result of extracting a length from + this's response's header list. + +

    5. If length is not an integer, then set it to 0. + +

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

    7. Set xhr's state to done. + +

    8. Unset xhr's send() flag. + +

    9. Fire an event named readystatechange at xhr. + +

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

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

    + +

    To handle errors for an {{XMLHttpRequest}} object xhr, 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!!exception}}" + {{DOMException}}. + +

    3. Otherwise, if xhr's response's + aborted flag is set, run the request error steps for xhr, + abort, and "{{AbortError!!exception}}" + {{DOMException}}. + +

    4. Otherwise, if xhr's response is a + network error, then run the request error steps for xhr, + {{XMLHttpRequestEventTarget/error}}, and "{{NetworkError!!exception}}" {{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. +

    + + +

    The abort() method

    + +
    +
    client . abort() +
    Cancels any network activity. +
    + +

    The abort() method steps are: + +

      +
    1. Abort this's + fetch controller. + +

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

    + + +

    Response

    + +

    The responseURL getter

    + +

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

    The status getter

    + +

    The status getter steps are to return +this's response's status. + + +

    The statusText getter

    + +

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

    The getResponseHeader() method

    + +

    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
    +
    + + +

    The getAllResponseHeaders() method

    + +

    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
    +
    + + +

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

    The overrideMimeType() method

    + +
    +
    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!!exception}}" {{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!!exception}}" {{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. +

    + + +

    The responseType getter and setter

    + +
    +
    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 the current global object is + not a {{Window}} object. + +

    When set: throws an "{{InvalidStateError!!exception}}" {{DOMException}} if state is + loading or done. + +

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

    + +

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

    The {{XMLHttpRequest/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!!exception}}" {{DOMException}}. + +

    3. If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +

    4. Set this's response type to the given value. +

    + + +

    The response getter

    + +
    +
    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 {{Blob/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. +

    + + +

    The responseText getter

    + +
    +
    client . responseText +
    +

    Returns response as text. + +

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

    + + +

    The responseXML getter

    + +
    +
    client . responseXML +
    +

    Returns the response as document. + +

    Throws an "{{InvalidStateError!!exception}}" {{DOMException}} if + {{XMLHttpRequest/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!!exception}}" {{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. +

    + + +

    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 {{XMLHttpRequest/readyState}} attribute changes + value, except when it changes to UNSENT. +
    loadstart + {{ProgressEvent}} + The fetch initiates. +
    progress + {{ProgressEvent}} + Transmitting data. +
    abort + {{ProgressEvent}} + When the fetch has been aborted. For instance, by invoking the + {{XMLHttpRequest/abort()}} method. +
    error + {{ProgressEvent}} + The fetch failed. +
    load + {{ProgressEvent}} + The fetch succeeded. +
    timeout + {{ProgressEvent}} + The author specified timeout has passed before the fetch completed. +
    loadend + {{ProgressEvent}} + The fetch completed (success or failure). +
    + + +

    Interface {{FormData}}

    + +
    +typedef (File or USVString) FormDataEntryValue;
    +
    +[Exposed=(Window,Worker)]
    +interface FormData {
    +  constructor(optional HTMLFormElement form, optional HTMLElement? submitter = null);
    +
    +  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 (an +entry list). It is initially empty. + +

    This section used to define +entry, an entry's +name and +value, and the +create an entry algorithm. These definitions have been +moved to the HTML Standard. [[HTML]] + +

    The +new FormData(form, submitter) +constructor steps are: + +

      +
    1. +

      If form is given, then: + +

        +
      1. +

        If submitter is non-null, then: + +

          +
        1. If submitter is not a submit button, then throw a + {{TypeError}}. + +

        2. If submitter's form owner is not form, then throw a + "{{NotFoundError!!exception}}" {{DOMException}}. +

        + +
      2. Let list be the result of constructing the entry list for + form and submitter. + +

      3. If list is null, then throw an "{{InvalidStateError!!exception}}" + {{DOMException}}. + +

      4. Set this's entry list to list. +

      +
    + +

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

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

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

    + +

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

    + +

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

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

    Interface {{ProgressEvent}}

    + +
    +[Exposed=(Window,Worker)]
    +interface ProgressEvent : Event {
    +  constructor(DOMString type, optional ProgressEventInit eventInitDict = {});
    +
    +  readonly attribute boolean lengthComputable;
    +  readonly attribute double loaded;
    +  readonly attribute double total;
    +};
    +
    +dictionary ProgressEventInit : EventInit {
    +  boolean lengthComputable = false;
    +  double loaded = 0;
    +  double total = 0;
    +};
    +
    + +

    Events using the {{ProgressEvent}} interface indicate some kind of progression. + +

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

    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 {{ProgressEvent/loaded}} +attribute initialized to transmitted, and if length is not 0, with the +{{ProgressEvent/lengthComputable}} attribute initialized to true and the {{ProgressEvent/total}} +attribute initialized to length. + + +

    Suggested names for events using the {{ProgressEvent}} interface

    + +

    This section is non-normative. + +

    The suggested {{Event/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. + + + + + + + + + + + +
    {{Event/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 {{Event/bubbles}} and {{Event/cancelable}} +attributes initialized to false, so it is suggested that for consistency all +events using the +{{ProgressEvent}} interface do the same. + + +

    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]] + + +

    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, +Chirag S Kumar, +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, +Noam Rosenthal, +Odin Hørthe Omdal, +Olli Pettay, +Pawel Glowacki, +Peter Michaux, +Philip Jägenstedt, +Philip Taylor, +Rashika Jaggi, +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 +(Apple, annevk@annevk.nl). diff --git a/xhr.bs b/xhr.bs index 0dc3c97..c7cd1ee 100644 --- a/xhr.bs +++ b/xhr.bs @@ -3,7 +3,7 @@ Group: WHATWG H1: XMLHttpRequest Shortname: xhr Text Macro: TWITTER xhrstandard -Text Macro: LATESTRD 2024-02 +Text Macro: LATESTRD 2025-08 Abstract: The XMLHttpRequest Standard defines an API that provides scripted client functionality for transferring data between a client and a server. Translation: ja https://triple-underscore.github.io/XHR-ja.html Translation: zh-Hans https://htmlspecs.com/xhr/