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 @@ +
+Group: WHATWG +Status: RD +Date: 2024-02-19 +H1: XMLHttpRequest +Shortname: xhr +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 +Translate IDs: enumdef-xmlhttprequestresponsetype xmlhttprequestresponsetype,dictdef-progresseventinit progresseventinit,typedefdef-formdataentryvalue formdataentryvalue ++ + +
+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 ++ + + +
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();
+}
+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: + +
+ + + +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]] + + + +
+[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: + +
send()
flag
+ arraybuffer
", "blob
",
+ "document
", "json
", and "text
"; initially the empty string.
+
+ send()
method sets it to a useful
+ fetch controller, but for simplicity it always holds a
+ fetch controller.
+
+ client = new XMLHttpRequest()
+ The
+new XMLHttpRequest()
+constructor steps are:
+
+
Set this's upload object to a new
+ XMLHttpRequestUpload
object.
+
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. + + +
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
+ |
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). + |
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.) + + +
open()
methodclient . 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:
+
+
If this's relevant global object is a {{Window}} object and its
+ associated Document
is not fully active, then throw an
+ "{{InvalidStateError!!exception}}" {{DOMException}}.
+
+
If method is not a method, then throw a + "{{SyntaxError!!exception}}" {{DOMException}}. + +
If method is a forbidden method, then throw a + "{{SecurityError!!exception}}" {{DOMException}}. + +
Normalize method. + +
Let parsedURL be the result of + encoding-parsing a URL url, relative to this's + relevant settings object. + +
If parsedURL is failure, then throw a "{{SyntaxError!!exception}}" + {{DOMException}}. + +
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.
+
+
If parsedURL's host is non-null, then: + +
If the username argument is not null, + set the username given parsedURL and + username. + +
If the password argument is not null, + set the password given parsedURL and + password. +
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}}. + +
Terminate this's + fetch controller. + +
A fetch can be ongoing at this point. + +
Set variables associated with the object as follows: + +
Unset this's send()
flag.
+
Unset this's upload listener flag. +
Set this's request method to method. +
Set this's request URL to parsedURL. +
Set this's synchronous flag if async is false; otherwise unset + this's synchronous flag. +
Set this's response to a network error. +
Set this's received bytes to the empty byte sequence. +
Set this's response object to null. +
Override MIME type is not overridden here as the
+ overrideMimeType()
method can be invoked before the open()
method.
+
+
If this's state is not opened, then: + +
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.
+
+
+
+
setRequestHeader()
methodclient . 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:
+
+
If this's state is not opened, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +
If this's send()
flag is set, then throw an
+ "{{InvalidStateError!!exception}}" {{DOMException}}.
+
+
Normalize value. + +
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. + +
If (name, value) is a forbidden request-header, then return. + +
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
+timeout
getter and setterclient . 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: + +
If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +
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. + + +
withCredentials
getter and setterclient . 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: + +
If this's state is not unsent or opened, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +
If this's send()
flag is set, then throw an
+ "{{InvalidStateError!!exception}}" {{DOMException}}.
+
+
Set this's cross-origin credentials to the given value. +
upload
getterclient . 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.
+
+
+
send()
methodclient . 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:
+
+
If this's state is not opened, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +
If this's send()
flag is set, then throw an
+ "{{InvalidStateError!!exception}}" {{DOMException}}.
+
+
If this's request method is `GET
` or `HEAD
`, then
+ set body to null.
+
+
If body is not null, then: + +
Let extractedContentType be null. + +
If body is a {{Document}}, then set this's request body to + body, serialized, + converted, and UTF-8 encoded. + +
Otherwise: + +
Let bodyWithType be the result of + safely extracting body. + +
Set this's request body to bodyWithType's + body. + +
Set extractedContentType to bodyWithType's + type. +
Let originalAuthorContentType be the result of getting
+ `Content-Type
` from this's author request headers.
+
+
If originalAuthorContentType is non-null, then: + +
If body is a {{Document}} or a {{USVString}}, then: + +
Let contentTypeRecord be the result of + parsing originalAuthorContentType. + +
If contentTypeRecord is not failure, contentTypeRecord's
+ parameters["charset
"] exists, and
+ parameters["charset
"] is not an
+ ASCII case-insensitive match for "UTF-8
", then:
+
+
Set contentTypeRecord's
+ parameters["charset
"] to "UTF-8
".
+
+
Let newContentTypeSerialized be the result of + serializing contentTypeRecord. + +
Set (`Content-Type
`,
+ newContentTypeSerialized) in this's author request headers.
+
Otherwise: + +
If body is an HTML document, then set
+ (`Content-Type
`, `text/html;charset=UTF-8
`) in this's
+ author request headers.
+
+
Otherwise, if body is an XML document, set
+ (`Content-Type
`, `application/xml;charset=UTF-8
`) in this's
+ author request headers.
+
+
Otherwise, if extractedContentType is not null, set
+ (`Content-Type
`, extractedContentType) in this's
+ author request headers.
+
If one or more event listeners are registered on this's upload object, then + set this's upload listener flag. + +
Let req be a new + request, initialized as + follows: + +
cors
".
+ include
";
+ otherwise "same-origin
".
+ xmlhttprequest
".
+ Unset this's upload complete flag. + +
Unset this's timed out flag. + +
If req's body is null, then set this's + upload complete flag. + +
Set this's send()
flag.
+
+
If this's synchronous flag is unset, then: + +
Fire a progress event named loadstart
at this
+ with 0 and 0.
+
+
Let requestBodyTransmitted be 0. + +
Let requestBodyLength be req's body's + length, if req's body is non-null; otherwise 0. + +
Assert: requestBodyLength is an integer. + +
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.
+
+
If this's state is not opened or this's
+ send()
flag is unset, then return.
+
+
Let processRequestBodyChunkLength, given a bytesLength, be these steps: + +
Increase requestBodyTransmitted by bytesLength. + +
If not roughly 50ms have passed since these steps were last invoked, then return. + +
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. + +
Let processRequestEndOfBody be these steps: + +
Set this's upload complete flag. + +
If this's upload listener flag is unset, then return. + +
Fire a progress event named progress
at this's
+ upload object with requestBodyTransmitted and requestBodyLength.
+
+
Fire a progress event named load
at this's
+ upload object with requestBodyTransmitted and requestBodyLength.
+
+
Fire a progress event named loadend
at this's
+ upload object with requestBodyTransmitted and requestBodyLength.
+
Let processResponse, given a response, be these steps: + +
Handle errors for this. + +
If this's response is a network error, then + return. + +
Fire an event named readystatechange
at this.
+
+
If this's response's body is null, + then run handle response end-of-body for this and return. + +
Let length be the result of extracting a length from + this's response's header list. + +
If length is not an integer, then set it to 0. + +
Let processBodyChunk given bytes be these steps: + +
Append bytes to this's received bytes. + +
If not roughly 50ms have passed since these steps were last invoked, then return. + +
If this's state is headers received, then set this's + state to loading. + +
Fire an event named readystatechange
at this.
+
+
Web compatibility is the reason readystatechange
+ fires more often than this's state changes.
+
+
Fire a progress event named progress
at this
+ with this's received bytes's length and
+ length.
+
Let processEndOfBody be this step: run handle response end-of-body for + this. + +
Let processBodyError be these steps: + +
Set this's response to a network error. + +
Run handle errors for this. +
Incrementally read this's response's + body, given processBodyChunk, processEndOfBody, + processBodyError, and this's relevant global object. +
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. + +
Let now be the present time. + + +
Run these steps in parallel: + +
+Otherwise, if this's synchronous flag is set: + +
Let processedResponse be false. + +
Let processResponseConsumeBody, given a response and + nullOrFailureOrBytes, be these steps: + +
If nullOrFailureOrBytes is not failure, then set this's + response to response. + +
If nullOrFailureOrBytes is a byte sequence, then append + nullOrFailureOrBytes to this's received bytes. + +
Set processedResponse 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. + + +
Pause until either processedResponse is true or this's + timeout is not 0 and this's timeout milliseconds have passed since + now. + +
If processedResponse is false, then set this's timed out flag and + terminate this's fetch controller. + +
Report timing for this's + fetch controller given the current global object. + +
Run handle response end-of-body for this. +
To handle response end-of-body for an +{{XMLHttpRequest}} object xhr, run these steps: + +
Handle errors for xhr. + +
If xhr's response is a network error, then + return. + +
Let transmitted be xhr's received bytes's + length. + +
Let length be the result of extracting a length from + this's response's header list. + +
If length is not an integer, then set it to 0. + +
If xhr's synchronous flag is unset, then fire a progress event
+ named progress
at xhr with transmitted and
+ length.
+
+
Set xhr's state to done. + +
Unset xhr's send()
flag.
+
+
Fire an event named readystatechange
at xhr.
+
+
Fire a progress event named load
at xhr with
+ transmitted and length.
+
+
Fire a progress event named loadend
at xhr with
+ transmitted and length.
+
To handle errors for an {{XMLHttpRequest}} object xhr, run these steps: + +
If xhr's send()
flag is unset, then return.
+
+
If xhr's timed out flag is set, then run the request error steps
+ for xhr, timeout
, and "{{TimeoutError!!exception}}"
+ {{DOMException}}.
+
+
Otherwise, if xhr's response's
+ 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 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: + +
Set xhr's state to done. + +
Unset xhr's send()
flag.
+
+
Set xhr's response to a network error. + +
If xhr's synchronous flag is set, then throw exception. + +
Fire an event named readystatechange
at xhr.
+
+
At this point it is clear that xhr's synchronous flag is unset. + +
If xhr's upload complete flag is unset, then: + +
Set xhr's upload complete flag. + +
If xhr's upload listener flag is set, then: + +
Fire a progress event named event at xhr's + upload object with 0 and 0. + +
Fire a progress event named loadend
at xhr's
+ upload object with 0 and 0.
+
Fire a progress event named event at xhr with 0 and 0. + +
Fire a progress event named loadend
at xhr
+ with 0 and 0.
+
abort()
methodclient . abort()
+ The abort()
method steps are:
+
+
Abort this's + fetch controller. + +
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
.
+
+
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.
+
responseURL
getterThe 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.
+
+
+
status
getterThe status
getter steps are to return
+this's response's status.
+
+
+
statusText
getterThe statusText
getter steps are to return
+this's response's status message.
+
+
+
getResponseHeader()
methodThe 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
+getAllResponseHeaders()
methodA byte sequence a is legacy-uppercased-byte less than a +byte sequence b if the following steps return true: + +
Let A be a, byte-uppercased. + +
Let B be b, byte-uppercased. + +
Return A is byte less than B. +
The getAllResponseHeaders()
method steps are:
+
+
Let output be an empty byte sequence. + +
Let initialHeaders be the result of running sort and combine with + this's response's header list. + +
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. + +
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. + +
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
+To get a response MIME type for an {{XMLHttpRequest}} object +xhr, run these steps: + +
Let mimeType be the result of extracting a MIME type + from xhr's response's header list. + +
If mimeType is failure, then set mimeType to text/xml
.
+
+
Return mimeType. +
To get a final MIME type for an {{XMLHttpRequest}} object +xhr, run these steps: + +
If xhr's override MIME type is null, return the result of + get a response MIME type for xhr. + +
Return xhr's override MIME type. +
To get a final encoding for an {{XMLHttpRequest}} object +xhr, run these steps: + +
Let label be null. + +
Let responseMIME be the result of get a response MIME type for + xhr. + +
If responseMIME's parameters["charset
"]
+ exists, then set label to it.
+
+
If xhr's override MIME type's
+ parameters["charset
"] exists, then set
+ label to it.
+
+
If label is null, then return null. + +
Let encoding be the result of getting an encoding from label. + +
If encoding is failure, then return null. + +
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: + +
Let finalMIME be the result of get a final MIME type for xhr. + +
If finalMIME is not an HTML MIME type or an XML MIME type, then + return. + +
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.
+
+
If finalMIME is an HTML MIME type, then: + +
Let charset be the result of get a final encoding for xhr. + +
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. + +
If charset is null, then set charset to UTF-8. + +
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]] + +
Flag document as an + HTML document. +
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. + +
If charset is null, then set charset to UTF-8. + + +
Set document's encoding to charset. + +
Set document's content type to finalMIME. + +
Set document's origin to xhr's + relevant settings object's origin. + +
Set xhr's response object to document. +
To get a text response for an +{{XMLHttpRequest}} object xhr, run these steps: + +
If xhr's response's body is null, + then return the empty string. + +
Let charset be the result of get a final encoding for xhr. + +
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.
+
+
If charset is null, then set charset to UTF-8. + +
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. + + +
overrideMimeType()
methodclient . 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:
+
+
If this's state is loading or done, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +
Set this's override MIME type to the result of + parsing mime. + +
If this's override MIME type is failure, then set this's
+ override MIME type to application/octet-stream
.
+
responseType
getter and setterclient . 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: + +
If the current global object is not a {{Window}} object and the given value is
+ "document
", then return.
+
+
If this's state is loading or done, then throw an + "{{InvalidStateError!!exception}}" {{DOMException}}. + +
If the current global object is a {{Window}} object and this's + synchronous flag is set, then throw an "{{InvalidAccessError!!exception}}" + {{DOMException}}. + +
Set this's response type to the given value. +
response
getterclient . response
+ Returns the response body. +
The response
getter steps are:
+
+
If this's response type is the empty string or "text
", then:
+
+
If this's state is not loading or done, then return + the empty string. + +
Return the result of getting a text response for this. +
If this's response object is failure, then return null. + +
If this's response object is non-null, then return it. + +
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]] + +
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.
+
+
Otherwise, if this's response type is "document
",
+ set a document response for this.
+
+
Otherwise: + +
Assert: this's response type is "json
".
+
+
Let jsonObject be the result of running parse JSON from bytes on + this's received bytes. If that threw an exception, then return null. + +
Set this's response object to jsonObject. +
Return this's response object. +
responseText
getterclient . 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:
+
+
If this's response type is not the empty string or "text
", then
+ throw an "{{InvalidStateError!!exception}}" {{DOMException}}.
+
+
If this's state is not loading or done, then return + the empty string. + +
Return the result of getting a text response for this. +
responseXML
getterclient . 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:
+
+
If this's response type is not the empty string or "document
",
+ then throw an "{{InvalidStateError!!exception}}" {{DOMException}}.
+
+
Assert: this's response object is not failure. + +
If this's response object is non-null, then return it. + +
Set a document response for this. + +
Return this's response object. +
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). + |
+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:
+
+
If form is given, then: + +
If submitter is non-null, then: + +
If submitter is not a submit button, then throw a + {{TypeError}}. + +
If submitter's form owner is not form, then throw a + "{{NotFoundError!!exception}}" {{DOMException}}. +
Let list be the result of constructing the entry list for + form and submitter. + +
If list is null, then throw an "{{InvalidStateError!!exception}}" + {{DOMException}}. + +
Set this's entry list to list. +
The
+append(name, value)
+and
+append(name, blobValue, filename)
+method steps are:
+
+
Let value be value if given; otherwise blobValue. + +
Let entry be the result of creating an entry with + name, value, and filename if given. + +
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:
+
+
If there is no entry whose name is + name in this's entry list, then return null. + +
Return the value of the first entry + whose name is name from this's + entry list. +
The getAll(name)
+method steps are:
+
+
If there is no entry whose name is + name in this's entry list, then return the empty list. + +
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:
+
+
Let value be value if given; otherwise blobValue. + +
Let entry be the result of creating an entry with + name, value, and filename if given. + +
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. + +
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. + + +
+[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.
+
+
+
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. + + +
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.
+
+
+
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]] + + +
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. +
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
spec:webdriver-bidi; type:dfn; text:event +spec:fetch; type:dfn; for:/; text:credentials