1. 介绍
本节为非规范性内容。
XMLHttpRequest
对象是一个用于获取资源的API。
名称XMLHttpRequest
是历史遗留的,名称本身与其功能无关。
一些简单的代码,用于处理通过网络获取的XML文档中的数据:
function processData( data) {
// 处理数据
}
function handler() {
if ( this . status == 200 &&
this . responseXML != null &&
this . responseXML. getElementById( 'test' ). textContent) {
// 成功!
processData( this . responseXML. getElementById( 'test' ). textContent);
} else {
// 发生错误
…
}
}
var client = new XMLHttpRequest();
client. onload = handler;
client. open( "GET" , "unicorn.xml" );
client. send();
如果你只想向服务器记录一条消息:
function log( message) {
var client = new XMLHttpRequest();
client. open( "POST" , "/log" );
client. setRequestHeader( "Content-Type" , "text/plain;charset=UTF-8" );
client. send( message);
}
或者你想检查服务器上的文档状态:
function fetchStatus( address) {
var client = new XMLHttpRequest();
client. onload = function () {
// 在网络错误的情况下,这可能无法给出可靠的结果
returnStatus( this . status);
}
client. open( "HEAD" , address);
client. send();
}
1.1. 规范历史
XMLHttpRequest
对象最初是在WHATWG的HTML工作中定义的。(基于微软多年前的实现。)它于2006年移交给W3C。扩展功能(如进度事件和跨域请求)被单独的草案(XMLHttpRequest Level
2)开发,直到2011年底,此时两个草案合并,XMLHttpRequest
从标准角度再次成为单一实体。到2012年底,它又回到了WHATWG。
当前草案的讨论可以在以下邮件列表档案中找到:
2. 术语
本规范依赖于Infra标准。[INFRA]
本规范使用来自DOM、DOM解析与序列化、编码、Fetch、文件API、HTML、URL、Web IDL和XML的术语。
[DOM] [DOM-PARSING] [ENCODING] [FETCH] [FILEAPI] [HTML] [URL] [WEBIDL] [XML] [XML-NAMES]
3. 接口 XMLHttpRequest
[Exposed =(Window ,DedicatedWorker ,SharedWorker )]interface :XMLHttpRequestEventTarget EventTarget { // 事件处理程序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 (); // 事件处理程序attribute EventHandler onreadystatechange ; // 状态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 ; // 请求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 (); // 响应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 ; };
一个XMLHttpRequest
对象关联了:
- 上传对象
- 一个
XMLHttpRequestUpload对象。 - 状态
- unsent、opened、headers received、loading 和 done 之一; 初始为 unsent。
send()已调用- 一个布尔值,初始为 false。
- 超时
- 一个无符号整数,初始为 0。
- 跨源 凭据
- 一个布尔值,初始为 false。
- 请求方法
- 一个方法。
- 请求 URL
- 一个 URL。
- 作者请求 标头
- 一个标头列表,初始为空。
- 请求体
- 初始为 null。
- 同步
- 一个布尔值,初始为 false。
- 上传 完成
- 一个布尔值,初始为 false。
- 上传 监听器
- 一个布尔值,初始为 false。
- 已超时
- 一个布尔值,初始为 false。
- 响应
- 一个响应,初始为一个网络错误。
- 已接收字节
- 一个字节序列,初始为空字节序列。
- 响应类型
- 空字符串、"
arraybuffer"、"blob"、 "document"、"json" 和 "text" 之一;初始为空字符串。 - 响应对象
- 一个对象、failure 或 null,初始为 null。
- fetch 控制器
- 一个fetch 控制器,初始为一个新的fetch
控制器。
send()方法会将其设为有用的 fetch 控制器,但为简单起见,它总是持有一个 fetch 控制器。 - 覆盖 MIME 类型
- 一个MIME 类型或 null,初始为 null。当调用
overrideMimeType()时可以获得一个值。
3.1. 构造函数
client = new XMLHttpRequest()- 返回一个新的
XMLHttpRequest对象。
new XMLHttpRequest()
构造函数的步骤如下:
3.2. 垃圾回收
一个 XMLHttpRequest
对象不得被垃圾回收,如果它的
状态是
opened 且 send()
已调用为 true,
headers received,或 loading,并且它有一个或多个
事件监听器
已注册,且其 type 是
readystatechange、
progress、
abort、
error、
load、
timeout
和
loadend
之一。
如果一个XMLHttpRequest
对象在其连接仍然打开的情况下被垃圾回收,用户代理必须终止该XMLHttpRequest
对象的请求控制器。
3.3. 事件处理程序
以下是事件处理程序(及其对应的事件类型)
,在继承自XMLHttpRequestEventTarget接口的对象上必须作为属性支持:
| 事件处理程序 | 事件类型 |
|---|---|
onloadstart
| loadstart
|
onprogress
| progress
|
onabort
| abort
|
onerror
| error
|
onload
| load
|
ontimeout
| timeout
|
onloadend
| loadend
|
以下是事件处理程序(及其对应的事件类型),仅在XMLHttpRequest
对象上作为属性支持:
| 事件处理程序 | 事件类型 |
|---|---|
onreadystatechange
| readystatechange
|
3.4. 状态
client . readyState-
返回client的状态。
readyState获取步骤如下,返回表格第二列的值,对应第一列中this的状态:
| 未发送 | UNSENT(数值 0)
| 对象已构建。 |
| 已打开 | OPENED(数值 1)
| open()方法已成功调用。在此状态下,可以使用setRequestHeader()设置请求头,并使用send()方法发起请求。
|
| 头信息已接收 | HEADERS_RECEIVED
(数值 2)
| 所有重定向(如果有)已跟随,所有响应头信息已接收。 |
| 加载中 | LOADING(数值 3)
| 响应体正在接收中。 |
| 已完成 | DONE(数值 4)
| 数据传输已完成,或传输过程中出现问题(如无限重定向)。 |
3.5. 请求
在
XMLHttpRequestUpload
对象上注册一个或多个事件监听器会导致一次CORS 预检请求。(这是因为
注册事件监听器会导致上传监听器被设为 true,而这又会导致
use-CORS-preflight 标志被设置。)
3.5.1. open()方法
client . open(method, url [, async = true [, username = null [, password = null]]])-
如果method不是有效方法,或者url无法解析,则抛出"
SyntaxError"DOMException。如果method与`
CONNECT`、`TRACE`或`TRACK`不区分大小写匹配,则抛出"SecurityError"DOMException。如果async为false,当前全局对象是
Window对象,且timeout属性不为零,或者responseType属性不为空,则抛出"InvalidAccessError"DOMException。
在非工作者环境中的同步XMLHttpRequest正在逐步从Web平台移除,因为它对终端用户体验有不利影响。(这是一个需要多年才能完成的过程。)开发者不得在Window对象作为当前全局对象时传递async参数为false。用户代理强烈建议在开发者工具中对此类用法发出警告,并可尝试抛出一个"InvalidAccessError"DOMException。
open(method, url)和open(method, url, async, username, password)方法的步骤如下:
-
如果this的相关全局对象是一个
Window对象,并且其相关Document不是完全活动状态,则抛出一个"InvalidStateError"DOMException。 -
如果method不是有效方法,则抛出一个"
SyntaxError"DOMException。 -
如果method是一个禁用方法,则抛出一个"
SecurityError"DOMException。 -
规范化method。
-
如果parsedURL解析失败,则抛出一个"
SyntaxError"DOMException。 -
如果未指定async参数,则将async设置为true,并将username和password设置为null。
遗憾的是,遗留内容阻止了将async参数为
undefined的情况与省略该参数视为相同。 -
如果parsedURL的主机非空,则:
-
如果async为false,当前全局对象是一个
Window对象,并且this的timeout不为0,或者this的response type不为空,则抛出一个"InvalidAccessError"DOMException。 -
此时可能仍有一个fetch正在进行。
-
将与该对象关联的变量设置如下:
-
将 this 的
send()已调用设为 false。
覆盖 MIME 类型在这里未被覆盖,因为
overrideMimeType()方法可以在open()方法之前调用。 -
-
-
在 this 上触发一个事件,其名称为
readystatechange。
定义了两个open()方法的原因是由于编写XMLHttpRequest标准时使用的编辑软件的限制。
3.5.2.
setRequestHeader() 方法
client . setRequestHeader(name, value)-
向现有请求标头追加一个值,或添加一个新的请求标头。
如果 状态不是 opened,或
send()已调用为 true,则抛出一个 "InvalidStateError"DOMException。如果 name 不是标头名称,或 value 不是标头值,则抛出一个 "
SyntaxError"DOMException。
setRequestHeader(name, value)
方法步骤是:
-
如果 this 的 状态不是 opened,则抛出一个 "
InvalidStateError"DOMException。 -
如果 this 的
send()已调用为 true,则抛出一个 "InvalidStateError"DOMException。 -
规范化 value。
-
如果 name 不是标头名称,或 value 不是 标头值,则抛出一个 "
SyntaxError"DOMException。空字节序列表示一个空的标头值。
-
如果 (name, value) 是一个被禁止的请求标头,则返回。
下面的代码演示了当设置同一个头两次时发生了什么:
// 下面的脚本:
var client = new XMLHttpRequest();
client. open( 'GET' , 'demo.cgi' );
client. setRequestHeader( 'X-Test' , 'one' );
client. setRequestHeader( 'X-Test' , 'two' );
client. send();
// ……结果发送了如下头:
// X-Test: one, two
3.5.3.
timeout 获取器和设置器
client . timeout-
可以设置为以毫秒为单位的时间。当设置为非零值时,将导致 获取在给定时间经过后终止。当该 时间已过、请求尚未完成,且 同步为 false 时,则会 分派一个
timeout事件;否则将 抛出一个 "TimeoutError"DOMException(对于send()方法)。设置时:如果 同步为 true,且当前全局对象是一个
Window对象,则抛出一个 "InvalidAccessError"DOMException。
timeout getter 步骤是返回
this 的超时。
timeout
setter 步骤是:
-
如果当前全局对象是一个
Window对象,且 this 的 同步为 true,则抛出一个 "InvalidAccessError"DOMException。
这意味着
timeout
属性可以在
获取进行中
设置。如果发生这种情况,它仍将相对于
获取的开始时间来衡量。
3.5.4.
withCredentials 获取器和设置器
client . withCredentials-
当要在跨源请求中包含凭据时为 true。当要在跨源请求中排除它们, 且要忽略其响应中的 cookie 时为 false。 初始为 false。
设置时:如果状态不是 unsent 或 opened,或
send()已调用为 true,则抛出一个 "InvalidStateError"DOMException。
withCredentials getter 步骤是
返回 this 的跨源
凭据。
withCredentials
setter 步骤是:
-
如果 this 的 状态不是 unsent 或 opened,则 抛出一个 "
InvalidStateError"DOMException。 -
如果 this 的
send()已调用为 true,则抛出一个 "InvalidStateError"DOMException。
3.5.5. upload 获取器
client . upload-
返回关联的
XMLHttpRequestUpload对象。当数据被传输到服务器时,它可用于收集传输信息。
upload getter 步骤是返回
this 的上传对象。
3.5.6. send() 方法
client . send([body = null])-
发起请求。body 参数提供请求体(如有), 且如果请求方法是
GET或HEAD,则会被忽略。如果状态不是 opened,或
send()已调用为 true,则抛出一个 "InvalidStateError"DOMException。
send(body) 方法
步骤是:
-
如果 this 的 状态不是 opened,则抛出一个 "
InvalidStateError"DOMException。 -
如果 this 的
send()已调用为 true,则抛出一个 "InvalidStateError"DOMException。 -
如果 body 不是 null:
-
令 extractedContentType 为 null。
-
如果 body 是一个
Document, 则将 this 的请求体设为 body,经过序列化、 转换并经过 UTF-8 编码后的结果。 -
否则:
-
令 originalAuthorContentType 为从 this 的作者请求标头中取得 `
Content-Type` 的结果。 -
如果 originalAuthorContentType 非 null:
-
如果 body 是一个
Document对象、一个URLSearchParams对象,或一个 字符串:-
令 contentTypeRecord 为解析 originalAuthorContentType 的结果。
-
如果 contentTypeRecord 不是 failure, contentTypeRecord 的 parameters["
charset"] 存在,且 parameters["charset"] 不是 与 "UTF-8" ASCII 大小写不敏感匹配:
-
-
-
否则:
-
-
令 req 为一个新的 请求,初始化如下:
- 方法
- this 的请求方法。
- URL
- this 的请求 URL。
- 标头列表
- this 的作者请求标头。
- unsafe-request 标志
- 已设置。
- body
- this 的请求体。
- client
- this 的相关设置对象。
- 模式
- "
cors"。 - use-CORS-preflight 标志
- 如果 this 的上传监听器为 true,则已设置。
- 凭据模式
- 如果 this 的跨源凭据为 true,则为
"
include"; 否则为 "same-origin"。 - use-URL-credentials 标志
- 如果 this 的请求 URL包含凭据,则已设置。
- 发起者类型
- "
xmlhttprequest"。
-
将 this 的
send()已调用设为 true。 -
-
令 requestBodyTransmitted 为 0。
-
令 requestBodyLength 为 req 的body 的 长度,如果 req 的body 为非 null;否则为 0。
-
断言:requestBodyLength 是一个整数。
-
如果 this 的上传完成为 false,且 this 的 上传监听器为 true,则在 this 的上传对象上触发一个进度事件,其名称为
loadstart, 并带有 requestBodyTransmitted 和 requestBodyLength。 -
如果 this 的状态不是 opened,或 this 的
send()已调用为 false,则返回。 -
令 processRequestBodyChunkLength,给定一个 bytesLength,为以下步骤:
-
将 requestBodyTransmitted 增加 bytesLength。
-
如果距离上次调用这些步骤尚未大约经过 50ms,则返回。
-
如果 this 的上传 监听器为 true,则在 this 的上传对象上触发一个进度事件, 其名称为
progress,并带有 requestBodyTransmitted 和 requestBodyLength。
这些步骤仅在传输新字节时调用。
-
-
令 processRequestEndOfBody 为以下步骤:
-
令 processResponse,给定一个 response,为以下步骤:
-
将 this 的fetch 控制器设为以 processRequestBodyChunkLength 设为 processRequestBodyChunkLength、processRequestEndOfBody 设为 processRequestEndOfBody,以及 processResponse 设为 processResponse 来获取 req 的结果。
-
令 now 为当前时间。
-
并行运行这些步骤:
-
-
令 processedResponse 为 false。
-
令 processResponseConsumeBody,给定一个 response 和 nullOrFailureOrBytes,为以下步骤:
-
将 this 的fetch 控制器设为以 processResponseConsumeBody 设为 processResponseConsumeBody 且 useParallelQueue 设为 true 来获取 req 的结果。
-
令 now 为当前时间。
-
暂停,直到 processedResponse 为 true,或者 this 的 超时不是 0 且从 now 起已经过 this 的超时毫秒。
-
如果 processedResponse 为 false,则将 this 的已超时 设为 true,并 终止 this 的fetch 控制器。
-
要为一个
XMLHttpRequest
对象 xhr处理响应体结束,运行以下步骤:
-
为 xhr处理错误。
-
如果 length 不是一个整数,则将其设为 0。
-
如果 xhr 的同步为 false,则在 xhr 上触发一个进度 事件, 其名称为
progress,并带有 transmitted 和 length。 -
将 xhr 的状态设为 done。
-
将 xhr 的
send()已调用设为 false。 -
在 xhr 上触发一个事件,其名称为
readystatechange。
要为一个
XMLHttpRequest
对象 xhr处理错误,运行以下步骤:
-
如果 xhr 的
send()已调用为 false,则返回。 -
如果 xhr 的已 超时为 true,则为 xhr、
timeout和 "TimeoutError"DOMException运行请求错误步骤。 -
否则,如果 xhr 的响应的 aborted 标志已设置,则为 xhr、
abort和 "AbortError"DOMException运行请求错误步骤。 -
否则,如果 xhr 的响应是一个 网络错误,则为 xhr、
error和 "NetworkError"DOMException运行请求错误步骤。
对于一个 XMLHttpRequest
对象 xhr、
event,以及可选的 exception,请求错误
步骤是:
-
将 xhr 的状态设为 done。
-
将 xhr 的
send()已调用设为 false。 -
在 xhr 上触发一个事件,其名称为
readystatechange。此时已经清楚,xhr 的同步为 false。
-
如果 xhr 的上传完成为 false:
-
在 xhr 上触发一个进度事件,其名称为 event, 并带有 0 和 0。
3.5.7. abort() 方法
client . abort()- 取消任何网络活动。
abort() 方法步骤是:
-
如果 this 的状态是 opened 且 this 的
send()已调用 为 true、headers received 或 loading,则为 this 和abort运行 请求错误 步骤。 -
如果 this 的状态是 done,则将 this 的 状态设为 unsent,并将 this 的响应设为一个网络错误。
不会分派
readystatechange事件。
3.6. 响应
3.6.1.
responseURL 获取器
responseURL getter 步骤是:如果
this 的响应的 URL 为
null,则返回空字符串;否则返回其在设置了 排除片段标志 时的
序列化。
3.6.2.
status 获取器
status 获取器的步骤是返回 此对象 的 响应 的 状态。
3.6.3.
statusText 获取器
statusText 获取器的步骤是返回 此对象 的 响应 的 状态消息。
3.6.4.
getResponseHeader() 方法
getResponseHeader(name) 方法步骤是返回从
此对象 的 响应 的 头部列表中获取 name 的结果。
Fetch 标准过滤了 此对象 的 响应的 头部列表。[FETCH]
对于以下脚本:
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" ));
}
}
print() 函数将处理类似的内容:
text/plain; charset=UTF-8
3.6.5. getAllResponseHeaders() 方法
如果以下步骤返回 true,则字节序列 a 被定义为 传统大写字节小于 字节序列 b:
getAllResponseHeaders() 方法的步骤是:
-
将 output 设为空字节序列。
-
将 headers 设为对 initialHeaders 进行 升序排序 的结果,其中当 a 的 名称 比 b 的名称 传统大写字节小于 时,a 小于 b。
不幸的是,这在与已部署内容的兼容性方面是必要的。
-
对于每个 header 在 headers 中,附加 header 的 名称,后跟 0x3A 0x20 字节对,再跟 header 的 值,最后跟 0x0D 0x0A 字节对,添加到 output。
-
返回 output。
Fetch 标准过滤了 此对象 的 响应的 头部列表。[FETCH]
对于以下脚本:
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());
}
}
print() 函数将处理类似的内容:
connection: Keep-Alive
content-type: text/plain; charset=utf-8
date: Sun, 24 Oct 2004 04:58:38 GMT
keep-alive: timeout=15, max=99
server: Apache/1.3.31 (Unix)
transfer-encoding: chunked
3.6.6. 响应主体
要为 XMLHttpRequest 对象 xhr 获取响应 MIME 类型,执行以下步骤:
-
将 mimeType 设为从 xhr 的 响应 的 头部列表中 提取 MIME 类型 的结果。
-
如果 mimeType 失败,则将 mimeType 设置为
text/xml。 -
返回 mimeType。
要为 XMLHttpRequest 对象 xhr 获取最终的 MIME 类型,执行以下步骤:
-
如果 xhr 的 覆盖 MIME 类型 为空,则返回为 xhr 获取响应 MIME 类型 的结果。
-
返回 xhr 的 覆盖 MIME 类型。
要为 XMLHttpRequest 对象 xhr 获取最终编码,执行以下步骤:
-
将 label 设为空。
-
将 responseMIME 设为为 xhr 获取响应 MIME 类型 的结果。
-
如果 xhr 的 覆盖 MIME 类型 的 参数["
charset"] 存在, 则将 label 设置为它。 -
如果 label 为空,则返回空。
-
将 encoding 设为从 label 获取编码 的结果。
-
如果 encoding 失败,则返回空。
-
返回 encoding。
以上步骤故意不使用 获取最终 MIME 类型,因为这将不与 Web 兼容。
要为 XMLHttpRequest 对象 xhr 设置文档响应,执行以下步骤:
-
将 finalMIME 设为为 xhr 获取最终 MIME 类型 的结果。
-
如果 finalMIME 不是 HTML MIME 类型 或 XML MIME 类型,则返回。
-
如果 xhr 的 响应类型 为空字符串且 finalMIME 为 HTML MIME 类型,则返回。
这是限制 xhr 的 响应类型 为 "
document" 以防止破坏遗留内容。 -
如果 finalMIME 是 HTML MIME 类型, 则:
-
否则,将 document 设为 文档,其表示在 xhr 的 接收到的字节上运行 XML 解析器且禁用XML 脚本支持 的结果。如果失败(不支持的字符编码、命名空间格式错误等),则返回空。 [HTML]
不会加载引用的资源,也不会应用任何相关的 XSLT。
-
如果 charset 为空,则将 charset 设置为 UTF-8。
-
将 document 的 编码设置为 charset。
-
将 document 的 内容类型设置为 finalMIME。
-
将 xhr 的 响应对象 设置为 document。
要为 XMLHttpRequest 对象 xhr 获取文本响应,执行以下步骤:
-
将 charset 设为为 xhr 获取最终编码 的结果。
-
如果 xhr 的 响应类型为空字符串,charset为空,且为 xhr 获取最终 MIME 类型 的结果为 XML MIME 类型,则使用 XML 规范中规定的规则确定编码。将 charset 设置为确定的编码。 [XML] [XML-NAMES]
这是为了保持非遗留的 xhr 响应类型值 "
text" 的简洁。 -
如果 charset 为空,则将 charset 设置为 UTF-8。
作者强烈建议始终使用 UTF-8 编码其资源。
3.6.7.
overrideMimeType() 方法
client . overrideMimeType(mime)-
作用是使响应的 `
Content-Type` 头部值看起来像是 mime。(它不会更改头部。)如果 状态 为 loading 或 done,则抛出 "
InvalidStateError"DOMException。
overrideMimeType(mime) 方法的步骤为:
-
如果 this 的状态是 loading 或 done,则抛出一个 "
InvalidStateError"DOMException。 -
将 this 的覆盖 MIME 类型设为 解析 mime 的结果。
-
如果 this 的覆盖 MIME 类型是 failure,则将 this 的 覆盖 MIME 类型设为
application/octet-stream。
3.6.8.
responseType 获取器和设置器
client . responseType [ = value ]-
返回响应类型。
可以设置以更改响应类型。值为: 空字符串(默认)、 "
arraybuffer"、 "blob"、 "document"、 "json" 和 "text"。设置时:如果当前全局对象不是
Window对象,则将其设置为 "document" 会被忽略。设置时:如果状态是 loading 或 done,则抛出一个 "
InvalidStateError"DOMException。设置时:如果 同步为 true,且当前全局对象是一个
Window对象,则抛出一个 "InvalidAccessError"DOMException。
responseType getter 步骤是返回
this 的响应类型。
responseType
setter 步骤是:
-
如果 this 的状态是 loading 或 done,则抛出一个 "
InvalidStateError"DOMException。 -
如果当前全局对象是一个
Window对象,且 this 的 同步为 true,则抛出一个 "InvalidAccessError"DOMException。
3.6.9.
response 获取器
client . response-
返回响应主体。
response 获取器的步骤为:
-
如果 this 的响应类型是 "
arraybuffer",则将 this 的 响应对象设为一个表示 this 的 已接收字节的新ArrayBuffer对象。如果 这抛出异常,则将 this 的响应对象 设为 failure 并返回 null。分配一个
ArrayBuffer对象不保证会成功。[ECMASCRIPT] -
否则,如果 this 的响应类型是 "
blob", 则将 this 的响应对象设为一个表示 this 的 已接收字节的新Blob对象,其中type设置为为 this取得最终 MIME 类型的结果。 -
否则:
3.6.10.
responseText 获取器
client . responseText-
返回响应为文本格式。
如果
responseType不是空字符串或 "text", 则抛出 "InvalidStateError"DOMException。
responseText 获取器的步骤为:
-
如果 this 的响应类型不是空字符串或 "
text", 则 抛出一个 "InvalidStateError"DOMException。
3.6.11.
responseXML 获取器
client . responseXML-
返回响应为文档格式。
如果
responseType不是空字符串或 "document", 则抛出 "InvalidStateError"DOMException。
responseXML 获取器的步骤为:
-
如果 this 的响应类型不是空字符串或 "
document", 则抛出一个 "InvalidStateError"DOMException。
3.7. 事件概要
本节为非规范性内容。
以下事件会在 XMLHttpRequest 或 XMLHttpRequestUpload 对象上被触发:
| 事件名称 | 接口 | 触发时机…… |
|---|---|---|
readystatechange
| Event
| readyState 属性改变时触发,除了它改变为 UNSENT 时。
|
loadstart
| ProgressEvent
| 请求开始时触发。 |
progress
| ProgressEvent
| 数据传输时触发。 |
abort
| ProgressEvent
| 请求被中止时触发。例如,通过调用 abort() 方法。
|
error
| ProgressEvent
| 请求失败时触发。 |
load
| ProgressEvent
| 请求成功时触发。 |
timeout
| ProgressEvent
| 在请求超时时触发。 |
loadend
| ProgressEvent
| 请求完成(无论成功或失败)时触发。 |
4. 接口 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 >; };
每个 FormData
对象都有一个关联的 entry list (一个 条目列表)。它最初是空的。
本节曾定义了 条目、条目的 名称 和 值,以及 创建条目 的算法。这些定义已被移至 HTML 标准中。[HTML]
new FormData(form, submitter) 构造器步骤如下:
-
如果 form 被提供,则:
-
如果 submitter 非空,则:
-
如果 submitter 的 表单所有者 不是 form,则 抛出一个 "
NotFoundError"DOMException。
-
令 list 为 构建表单数据集 的结果,针对 form 和 submitter。
-
如果 list 为 null,则 抛出 一个 "
InvalidStateError"DOMException。
-
append(name, value) 和 append(name, blobValue, filename)
方法步骤如下:
-
如果给定值,则将 value 设为 value;否则设为 blobValue。
-
令 entry 为通过 创建条目 得到的结果,使用 name、value 和可选的 filename。
参数 value 和 blobValue 同时存在的原因是因为用于编写 XMLHttpRequest 标准的编辑软件的限制。
delete(name)
方法步骤是从 this 的
条目
列表中移除所有
名称为 name 的条目。
get(name) 方法
步骤是:
getAll(name)
方法步骤是:
has(name) 方法
步骤是:如果在 this 的
条目
列表中存在一个
名称为 name 的条目,则返回 true;否则返回 false。
set(name, value)
和
set(name, blobValue, filename)
方法步骤是:
-
令 value 为 value,如果已给定;否则为 blobValue。
-
令 entry 为用 name、value 以及 filename(如果已给定)创建条目的结果。
存在一个名为 value 的参数以及 blobValue 的原因,是由于用于编写 XMLHttpRequest 标准的编辑软件存在限制。
要迭代的值对是 this 的条目列表的 条目,其中键为名称, 值为值。
5. 接口 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 = 0;loaded double = 0; };total
事件 使用
ProgressEvent
接口表示某种进展。
lengthComputable、loaded 和 total getter 的步骤是返回它们的初始值。
5.1. 使用 ProgressEvent
接口触发事件
为了 触发一个名为
e 的进度事件 在 target 上,给定 transmitted 和 length,意味着使用 触发一个事件 名为 e 在 target 上,使用 ProgressEvent,并将
loaded
属性初始化为 transmitted,如果 length 不为 0,则将 lengthComputable
属性初始化为 true,并将 total
属性初始化为 length。
5.2. 使用 ProgressEvent
接口的建议事件名称
本节非规范性。
使用 事件 和
ProgressEvent
接口时,建议的 type
属性值总结在下表中。规范编辑者可以根据具体情况调整细节,但强烈建议与 WHATWG 社区讨论他们的使用,以确保从熟悉该主题的人那里获得意见。
type
属性值
| 描述 | 次数 | 时间点 |
|---|---|---|---|
loadstart
| 进度开始。 | 一次。 | 最初。 |
progress
| 正在进行。 | 一次或多次。 | 在 loadstart 被分发之后。
|
error
| 进度失败。 | 零次或一次(互斥)。 | 在最后一个 progress 被分发之后。
|
abort
| 进度被终止。 | ||
timeout
| 由于预设时间到期,进度被终止。 | ||
load
| 进度成功。 | ||
loadend
| 进度停止。 | 一次。 | 在 error、abort、timeout 或 load 之一被 分发之后。
|
error、abort、timeout 和 load 事件类型是互斥的。
在整个 Web 平台中,error、abort、timeout 和 load 事件类型的 bubbles
和 cancelable
属性初始值为 false,因此建议为了保持一致,所有使用 事件 和 ProgressEvent
接口的事件都遵循此规则。
5.3. 安全注意事项
对于跨域请求,需要某种类型的选择加入,例如 Fetch 标准中定义的 CORS 协议,在 事件 使用
ProgressEvent
接口之前,因为会泄露无法通过其他方式获得的信息(例如大小)。[FETCH]
5.4. 示例
在这个示例中,XMLHttpRequest
与前述章节中定义的概念相结合,使用 HTML 的
progress
元素一起显示获取资源的过程。
<!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 >
完整可运行的代码当然会更加复杂,并处理更多场景,例如网络错误或终端用户终止请求的情况。
致谢
感谢 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,和 Zhenbin Xu 等人为该标准做出的贡献。
特别感谢首次实现 XMLHttpRequest
接口的微软员工,该接口首次通过 Windows Internet Explorer 浏览器广泛部署。
特别感谢 Ian Hickson 起草了最初版本的本规范,该规范最初在 HTML 标准(当时是 Web Applications 1.0)中。[HTML]
特别感谢 W3C SVG 工作组在 SVG 微型 DOM
中起草了原始的 ProgressEvent
类。
本标准由 Anne van Kesteren(Apple,annevk@annevk.nl)撰写。
知识产权声明
版权所有 © WHATWG(Apple、Google、Mozilla、Microsoft)。本作品采用 Creative Commons Attribution 4.0 International License 进行许可。若部分内容已被纳入源代码,则源代码中的该部分根据 BSD 3-Clause License 许可。
这是现行标准。对专利审查版本感兴趣的用户应查看 现行标准审查草案。