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-Charset
Accept-Encoding
Access-Control-Request-Headers
Access-Control-Request-Method
Connection
Content-Length
cookie
Cookie2
Date
DNT
Expect
Host
Keep-Alive
Origin
Referer
TE
Trailer
Transfer-Encoding
Upgrade
User-Agent
Via
getResponseHeader(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
和 statusText
status
属性表示 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
null
responseType
为 text
、""
、Document
时,xhr
对象上才有此属性,此时才能调用 xhr.responseXML
,否则抛错。3
种情况下值都为 null
:请求未完成、请求失败、请求成功但返回数据无法被正确解析时。upload
是一个XMLHttpRequestUpload
对象,用于收集传输信息。支持事件:
onloadstart
onprogress
onabort
ontimeout
onerror
onload
onloadend
xhr.upload.onprogress
在上传阶段(即xhr.send()
之后,xhr.readystate=2
之前)触发,每 50ms 触发一次。可获得上传信息、进度等。XMLHttpRequestEventTarget
对象,详见 事件补充。timeout
0
,即不设置超时。onloadstart
事件触发开始(即xhr.send()
开始),以onloadend
事件触发为结束。open()
方法后send()
方法前设置。其他浏览器无此限制,但仍然从xhr.send()
方法调用计时。timeout
,否则会报错。setTImeOut
实现。withCredentials
boolean
类型,默认值 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 个事件,分别如下:
onloadstart
onprogress
onabort
ontimeout
onerror
onload
onloadend
onreadystatechange
引用自 你真的会使用 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.onloadstart
xhr.upload.onprogress
xhr.upload.onload
xhr.upload.onloadend
//上传结束,下载阶段开始:xhr.onprogress
xhr.onload
xhr.onloadend
abort
/ timeout
/ error
时事件触发顺序xhr.onreadystatechange
事件,此时 readyState
为 4
如果上传阶段还没有结束,则依次触发以下事件:
xhr.upload.onprogress
xhr.upload.[onabort或ontimeout或onerror]
xhr.upload.onloadend
xhr.onprogress
事件xhr.[onabort或ontimeout或onerror]
事件xhr.onloadend
事件xhr.upload.onprogress
和 xhr.onprogress
的回调参数为 XMLHttpRequestEventTarget
对象。属性如下:
lengthComputable
boolean
值,表示资源是否有可计算的长度。loaded
total
xhr.upload.onprogress
事件触发于上传阶段,可用于获取上传进度。xhr.onprogress
事件触发于下载阶段,可用于获取下载进度。fetchAPI
整理。jQuery.ajax
的实现详解。axios
的实现详解。XMLHttpRequest
吗?在新项目中使用的是springboot编写的api,涉及到ajax跨域请求和传输文件的问题,在这里记录一下。<input type="button" onclick="test();" value="