81493369 2019-11-04
XMLHTTPRequest属性、方法、事件整理大全。
open(method:string, url:string, async?:boolean=true, username?:string, password: string)
HTTP 请求,但请求并未发送。method, 请求类型,如 GET 、POST 等,大小写不敏感。url, url 地址async, 是否异步,默认 true。
若为同步请求时
xhr.timeout值必须为 0。xhr.withCredentials值必须为 false。xhr.responseType值必须为"",(text 也不允许)。username, 用户名,一般不用。password, 密码,一般不用。send(body?:Object=null)
定义 HTTP 请求的数据( body ),当 method 为 GET、HEAD 时,该参数忽略。body 可为 ArrayBuffer、Blob、Document(类似 XML 格式数据)、DOMString(字符串)、FormData(表单)。
ArrayBuffer、Blob、Document、DOMString、Formdata 详细参考。
注意:body 参数会影响请求头部的 content-type 默认值。
data 是 Document 类型,同时也是 HTML Document 类型,则 content-type 默认值为 text/html;charset=UTF-8 ;否则为 application/xml;charset=UTF-8;data 是 DOMString 类型,content-type 默认值为 text/plain;charset=UTF-8 ;data 是 FormData 类型,content-type 默认值为 multipart/form-data; boundary=[xxx]如果 data 是其他类型,则不会设置 content-type 的默认值
如果用 xhr.setRequestHeader()手动设置了中 content-type 的值,以上默认值就会被覆盖。
若在断网状态下调用 xhr.send(data)方法,则会抛错:Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest'。一旦程序抛出错误,如果不 catch 就无法继续执行后面的代码,所以调用 xhr.send(data)方法时,应该用 try-catch 捕捉错误。
try{
xhr.send(data)
}catch(e) {
//doSomething...
};abort()
overrideMimeType(type:string)setRequestHeader(header:string, value:string)
content-type、cookie、accept-xxx等。open()方法后,send()方法前调用,否则会抛错。append方式。禁止设置以下请求头,否则会抛错。
Accept-CharsetAccept-EncodingAccess-Control-Request-HeadersAccess-Control-Request-MethodConnectionContent-LengthcookieCookie2DateDNTExpectHostKeep-AliveOriginRefererTETrailerTransfer-EncodingUpgradeUser-AgentViagetResponseHeader(header:string)
getAllResponseHeaders方法。getAllResponseHeaders()
有严格安全限制。如下:
Set-Cookie、Set-Cookie2字段值。跨域请求,只可获取simple response header和Access-Control-Expose-Headers(名词解释见下方),否则会报错:Refused to get unsafe header。故若想访问其他字段,需后端添加到 Access-Control-Expose-Headers 中。
simple response header包括的header字段有:Cache-Control,Content-Language,content-type,Expires,Last-Modified,Pragma。
> `Access-Control-Expose-Headers`:跨域请求独有,同域请求无。该字段中列举的 `header` 字段为服务器允许暴露给客户端访问的字段。 > 句法:```Access-Control-Expose-Headers: <header-name>, <header-name>, ...```
readyState
[只读属性]用于追踪 xhr 当前的状态,共有 5 种可能的值,分别对应 xhr不同的阶段。
每次 readyState 值变化时,都会触发 xhr.onreadystatechange 事件。
| 值 | 状态 | 描述 |
|---|---|---|
0 | UNSENT (初始状态,未打开) | 此时 xhr 对象被成功构造, open() 方法还未被调用 |
1 | OPENED (已打开,未发送) | open() 方法已被成功调用,send() 方法还未被调用。注意:只有 xhr 处于 OPENED 状态,才能调用 xhr.setRequestHeader()和 xhr.send() ,否则会报错 |
2 | HEADERS_RECEIVED (已获取响应头) | send() 方法已经被调用, 响应头和响应状态已经返回 |
3 | LOADING (正在下载响应体) | 响应体( response entity body )正在下载中,此状态下 xhr.response 可能已经有了响应数据 |
4 | DONE (整个数据传输过程结束) | 整个数据传输过程结束,不管本次请求是成功还是失败 |
status 和 statusTextstatus 属性表示 HTTP 响应状态码,如 200、302、400等。statusText 属性表示 HTTP响应状态的描述文本,如 OK、Not Found等。
注意,在 xhr.onload 事件中,不能简单的判断 xhr.status === 200,因为 20x、304等 HTTP 状态码也被认为是请求成功。
参考以下代码:
xhr.onload = function () {
//如果请求成功
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
//do successCallback
}
}responseType 和 response
可在 xhr.send() 前设置 responseType ,用于指定返回的响应数据类型。和 xhr.overrideMimeType() 方法效果相同,推荐使用 responseType。
xhr.responseType 为 json。部分浏览器不支持 xhr.responseType 为 blob。
| 值 | 描述 |
|---|---|
"" | 将 responseType 设为空字符串与设置为 text 相同, 是默认类型 (实际上是 DOMString )。 |
ArrayBuffer | response 是一个包含二进制数据的 JavaScript ArrayBuffer 。 |
blob | response 是一个包含二进制数据的 blob 对象 。 |
Document | response 是一个 HTML Document 或 XML XMLDocument ,这取决于接收到的数据的 MIME 类型。使用 xhr 获取 HTML 请参阅 HTML in XMLHttpRequest 。 |
json | response 是一个 JavaScript 对象。这个对象是通过将接收到的数据类型视为 json 解析得到的。 |
text | response 是包含在 DOMString 对象中的文本。 |
moz-chunked-arraybuffer | 与 ArrayBuffer 相似,但是数据会被接收到一个流中。使用此响应类型时,响应中的值仅在 progress 事件的处理程序中可用,并且只包含上一次响应 progress 事件以后收到的数据,而不是自请求发送以来收到的所有数据。在 progress 事件处理时访问 response 将返回到目前为止收到的数据。在 progress 事件处理程序之外访问, response 的值会始终为 null 。 |
ms-stream | response 是下载流的一部分;此响应类型仅允许下载请求,仅 IE 支持。 |
responseText
""responseType 为 text、""时,xhr 对象上才有此属性,此时才能调用 xhr.responseText ,否则抛错。2 种情况下值都为空字符串 "":请求未完成、请求失败。responseXML
nullresponseType 为 text、""、Document时,xhr 对象上才有此属性,此时才能调用 xhr.responseXML,否则抛错。3 种情况下值都为 null :请求未完成、请求失败、请求成功但返回数据无法被正确解析时。upload
是一个XMLHttpRequestUpload对象,用于收集传输信息。支持事件:
onloadstartonprogressonabortontimeoutonerroronloadonloadendxhr.upload.onprogress在上传阶段(即xhr.send()之后,xhr.readystate=2之前)触发,每 50ms 触发一次。可获得上传信息、进度等。XMLHttpRequestEventTarget 对象,详见 事件补充。timeout
0 ,即不设置超时。onloadstart 事件触发开始(即xhr.send()开始),以onloadend 事件触发为结束。open()方法后send()方法前设置。其他浏览器无此限制,但仍然从xhr.send()方法调用计时。timeout ,否则会报错。setTImeOut 实现。withCredentialsboolean 类型,默认值 false, 用于跨域请求时将 cookie 加入到 request header。
xhr.withCredentials与CORS什么关系
我们都知道,在发同域请求时,浏览器会将cookie自动加在request header中。但在发送跨域请求时,cookie并不会自动加在request header中。
造成这个问题的原因:在CORS标准有如下规定,默认情况下,浏览器在发送跨域请求时,不能发送任何认证信息(credentials)如cookies和HTTP authentication schemes。除非xhr.withCredentials为true。cookies也是一种认证信息,在跨域请求中,client端必须手动设置xhr.withCredentials=true,且server端也必须允许request能携带认证信息(即response header中包含Access-Control-Allow-Credentials:true),这样浏览器才会自动将cookie加在request header中。
注意,一旦跨域request能够携带认证信息,server端一定不能将Access-Control-Allow-Origin设置为*,而必须设置为请求页面的域名。
xhr 共有 8 个事件,分别如下:
onloadstartonprogressonabortontimeoutonerroronloadonloadendonreadystatechange引用自 你真的会使用 XMLHttpRequest 吗?
| 事件 | 触发条件 |
|---|---|
onreadystatechange | 每当xhr.readyState改变时触发;但xhr.readyState由非 0 值变为 0 时不触发。 |
onloadstart | 调用xhr.send()方法后立即触发,若xhr.send()未被调用则不会触发此事件。 |
onprogress | xhr.upload.onprogress在上传阶段(即xhr.send()之后,xhr.readystate=2之前)触发,每 50ms 触发一次;xhr.onprogress在下载阶段(即xhr.readystate=3时)触发,每 50ms 触发一次。 |
onload | 当请求成功完成时触发,此时xhr.readystate=4 |
onloadend | 当请求结束(包括请求成功和请求失败)时触发 |
onabort | 当调用xhr.abort()后触发 |
ontimeout | xhr.timeout不等于 0 ,由请求开始即 onloadstart 开始算起,当到达xhr.timeout 所设置时间请求还未结束即 onloadend ,则触发此事件。 |
onerror | 在请求过程中,若发生 Network error 则会触发此事件(若发生 Network error 时,上传还没有结束,则会先触发 xhr.upload.onerror,再触发 xhr.onerror ;若发生 Network error 时,上传已经结束,则只会触发xhr.onerror )。注意,只有发生了网络层级别的异常才会触发此事件,对于应用层级别的异常,如响应返回的xhr.statusCode是 4xx 时,并不属于 Network error ,所以不会触发 onerror 事件,而是会触发 onload 事件。 |
xhr.onreadystatechange (之后每次 readyState 变化时,都会触发一次)xhr.onloadstart //上传阶段开始:xhr.upload.onloadstartxhr.upload.onprogressxhr.upload.onloadxhr.upload.onloadend //上传结束,下载阶段开始:xhr.onprogressxhr.onloadxhr.onloadendabort / timeout / error 时事件触发顺序xhr.onreadystatechange 事件,此时 readyState 为 4如果上传阶段还没有结束,则依次触发以下事件:
xhr.upload.onprogressxhr.upload.[onabort或ontimeout或onerror]xhr.upload.onloadendxhr.onprogress 事件xhr.[onabort或ontimeout或onerror] 事件xhr.onloadend 事件xhr.upload.onprogress 和 xhr.onprogress 的回调参数为 XMLHttpRequestEventTarget 对象。属性如下:
lengthComputableboolean值,表示资源是否有可计算的长度。loadedtotalxhr.upload.onprogress 事件触发于上传阶段,可用于获取上传进度。xhr.onprogress 事件触发于下载阶段,可用于获取下载进度。fetchAPI 整理。jQuery.ajax 的实现详解。axios 的实现详解。XMLHttpRequest 吗?在新项目中使用的是springboot编写的api,涉及到ajax跨域请求和传输文件的问题,在这里记录一下。<input type="button" onclick="test();" value="