资讯专栏INFORMATION COLUMN

XMLHTTPRequest属性、方法、事件大全&详解。

roadtogeek / 2448人阅读

摘要:属性方法事件整理大全。有严格安全限制。值描述将设为空字符串与设置为相同,是默认类型实际上是。默认值为空字符串只有当为时,对象上才有此属性,此时才能调用,否则抛错。以下种情况下值都为空字符串请求未完成请求失败。

XMLHTTPRequest属性、方法、事件整理大全。

xhr 对象的方法

open(method:string, url:string, async?:boolean=true, username?:string, password: string)

用于创建 HTTP 请求,但请求并未发送。

method, 请求类型,如 GETPOST 等,大小写不敏感。

url, URL 地址

async, 是否异步,默认 true
若为同步请求时

xhr.timeout值必须为 0。

xhr.withCredentials值必须为 false。

xhr.responseType值必须为"",(text 也不允许)。

username, 用户名,一般不用。

password, 密码,一般不用。

send(body?:Object=null)

定义 HTTP 请求的数据( body ),当 methodGETHEAD 时,该参数忽略。body 可为 ArrayBufferBlob、Document(类似 XML 格式数据)、DOMString(字符串)、FormData(表单)。
ArrayBuffer、Blob、Document、DOMString、Formdata 详细参考。
注意:body 参数会影响请求头部的 content-type 默认值。

如果 dataDocument 类型,同时也是 HTML Document 类型,则 content-type 默认值为 text/html;charset=UTF-8 ;否则为 application/xml;charset=UTF-8;

如果 dataDOMString 类型,content-type 默认值为 text/plain;charset=UTF-8

如果 dataFormData 类型,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()

若请求已发出,则会终止请求,并将 readyState 置为 0.

调用后,应将 xhr 对象置为 null 以促进垃圾回收。由于内存原因,不建议重用 xhr 对象。
扩展阅读:和浏览器异步请求取消相关的那些事

overrideMimeType(type:string)
重写 response 的 content-type。功能如同 xhr.responseType,已可以摒弃。

setRequestHeader(header:string, value:string)

设置请求 HTTP 请求头信息。如content-typecookieaccept-xxx等。

header 参数大小写不敏感。

必须在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)

获取某个指定 header 字段的值。

header 字段不区分大小写。

有严格安全限制,详见getAllResponseHeaders方法。

getAllResponseHeaders()

获取 response 中所有 header 字段。

有严格安全限制。如下:

无论跨域或同域请求,无法获取Set-CookieSet-Cookie2字段值。

跨域请求,只可获取simple response headerAccess-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: , , ...```
xhr 的属性

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 (整个数据传输过程结束) 整个数据传输过程结束,不管本次请求是成功还是失败

statusstatusText
status 属性表示 HTTP 响应状态码,如 200302400等。
statusText 属性表示 HTTP响应状态的描述文本,如 OKNot Found等。
注意,在 xhr.onload 事件中,不能简单的判断 xhr.status === 200,因为 20x304HTTP 状态码也被认为是请求成功。
参考以下代码:

  xhr.onload = function () {
  //如果请求成功
  if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
    //do successCallback
  }
}

responseTyperesponse
可在 xhr.send() 前设置 responseType ,用于指定返回的响应数据类型。和 xhr.overrideMimeType() 方法效果相同,推荐使用 responseType

IE10/IE11 不支持 xhr.responseTypejson

部分浏览器不支持 xhr.responseTypeblob

描述
"" responseType 设为空字符串与设置为 text 相同, 是默认类型 (实际上是 DOMString )。
arraybuffer response 是一个包含二进制数据的 JavaScript ArrayBuffer
blob response 是一个包含二进制数据的 Blob 对象 。
document response 是一个 HTML DocumentXML 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

默认值为空字符串 ""

只有当 responseTypetext""时,xhr 对象上才有此属性,此时才能调用 xhr.responseText ,否则抛错。

只有当请求成功时,才能拿到正确值。以下 2 种情况下值都为空字符串 "":请求未完成、请求失败。

responseXML

默认值为 null

只有当 responseTypetext""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 事件触发为结束。

在 IE 中,只能在调用open()方法后send()方法前设置。其他浏览器无此限制,但仍然从xhr.send()方法调用计时。

不能为同步请求设置 timeout ,否则会报错。

早期较多浏览器不支持,可通过 setTImeOut 实现。

withCredentials
boolean 类型,默认值 false, 用于跨域请求时将 cookie 加入到 request header

xhr.withCredentialsCORS 什么关系
我们都知道,在发同域请求时,浏览器会将 cookie 自动加在 request header 中。但在发送跨域请求时, cookie 并不会自动加在 request header 中。
造成这个问题的原因:在 CORS 标准有如下规定,默认情况下,浏览器在发送跨域请求时,不能发送任何认证信息(credentials)如 cookiesHTTP authentication schemes 。除非 xhr.withCredentialstrue
cookies 也是一种认证信息,在跨域请求中, client 端必须手动设置 xhr.withCredentials=true ,且 server 端也必须允许 request 能携带认证信息(即 response header 中包含 Access-Control-Allow-Credentials:true),这样浏览器才会自动将 cookie 加在 request header 中。
注意,一旦跨域 request 能够携带认证信息, server 端一定不能将 Access-Control-Allow-Origin 设置为*,而必须设置为请求页面的域名。

xhr 的事件回调

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.statusCode4xx 时,并不属于 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 事件,此时 readystate4

如果上传阶段还没有结束,则依次触发以下事件:

xhr.upload.onprogress

xhr.upload.[onabort或ontimeout或onerror]

xhr.upload.onloadend

触发 xhr.onprogress 事件

触发 xhr.[onabort或ontimeout或onerror] 事件

触发 xhr.onloadend 事件

事件补充

xhr.upload.onprogressxhr.onprogress 的回调参数为 XMLHttpRequestEventTarget 对象。属性如下:

lengthComputable
【只读】,为 boolean值,表示资源是否有可计算的长度。

loaded
已接收或已上传的字节数。

total
文件总字节数。

xhr.upload.onprogress 事件触发于上传阶段,可用于获取上传进度。

xhr.onprogress 事件触发于下载阶段,可用于获取下载进度。

后续补充计划

fetchAPI 整理。

jQuery.ajax 的实现详解。

axios 的实现详解。

参考资料

DOMString、Document、FormData、Blob、File、ArrayBuffer 数据类型介绍

你真的会使用 XMLHttpRequest 吗?

XMLHttpRequest Level 2 使用指南

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106092.html

相关文章

  • 前端跨域之原因&amp;&amp;方案&amp;&amp;原理

    摘要:于是乎同源策略应运而生主要限制在于和无法读取。怎么绕过同源策略首先一般来说协议和端口造成的跨域问题大部分方法是没有办法绕过的。二级域名是寄存在主域名之下的域名。当主域名受到惩罚二级域名也会连带惩罚。 前言 这是一道前端跨不过躲不掉面试必备的知识,挣扎多年没能做到刻骨铭心深入脊髓,只能好好写篇博文记录起来了; 什么是跨域? 广义来说,A域执行的文档脚本试图去请求B域下的资源是不被允许的,...

    Zack 评论0 收藏0
  • 微信小程序云开发项目实战进阶 - 诗词大全&amp;成语接龙

    摘要:此时,就需要通过云函数更新数据库,新建云函数编辑更新数据根据更新已打开人数使用云函数更新某数据的打开人数数据库模糊查询小程序云开发可以使用正则表达式进行模糊查询。 1. 小程序功能 古诗词大全 成语大全 成语接龙 诗词飞花令 诗词分享、收藏 诗词接龙 唐诗宋词起名字 百家姓 猜谜语 2. 小程序地址 https://github.com/caochangkui/miniprogra...

    Ku_Andrew 评论0 收藏0
  • 温故js系列(12)-ajax&amp;&amp;优缺点&amp;&amp;node后端

    摘要:接收响应当请求发送到服务器端,收到响应后,响应的数据会自动填充对象的属性。一般而已状态代码为作为成功的标志。必要时,可以将查询字符串参数追加到的末尾,以便提交给服务器。后端实现可以自学一点后端知识,便于学习。 前端学习:教程&开发模块化/规范化/工程化/优化&工具/调试&值得关注的博客/Git&面试-前端资源汇总 欢迎提issues斧正:Ajax JavaScript-Ajax&&no...

    LiangJ 评论0 收藏0
  • 详解Vue3 Composition API优雅封装第三方组件

      我们时常会想在保持第三方组件原有功能(属性props、事件events、插槽slots、方法methods)的基础上,这些功能如何优化的实现?  以Element Plus的el-input为例:  在封装一个MyInput组件,把要使用的属性props、事件events和插槽slots、方法methods先要依照自己的需求来编写:  //MyInput.vue   <template&...

    3403771864 评论0 收藏0
  • 基于 HTTP 请求拦截,快速解决跨域和代理 Mock

    摘要:今天这篇文章,我们会介绍几种常见的方法和其中存在的问题,并提出如何基于请求拦截,快速解决跨域和代理问题的方案。因为没有修改该请求,只是延迟发送,这样就保持了原请求与业务服务器之间的所有鉴权等相关信息,由此解决了跨域访问无法携带的问题。 近几年,随着 Web 开发逐渐成熟,前后端分离的架构设计越来越被众多开发者认可,使得前端和后端可以专注各自的职能,降低沟通成本,提高开发效率。 在前后端...

    dreamGong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<