XMLHTTPRequest属性方法事件整理大全

43次阅读

共计 6672 个字符,预计需要花费 17 分钟才能阅读完成。

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: <header-name>, <header-name>, ...```

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 事件。
请求正常时,事件触发顺序
  1. 触发 xhr.onreadystatechange (之后每次 readyState 变化时,都会触发一次)
  2. 触发 xhr.onloadstart // 上传阶段开始:
  3. 触发 xhr.upload.onloadstart
  4. 触发 xhr.upload.onprogress
  5. 触发 xhr.upload.onload
  6. 触发 xhr.upload.onloadend // 上传结束,下载阶段开始:
  7. 触发 xhr.onprogress
  8. 触发 xhr.onload
  9. 触发 xhr.onloadend
发生 abort / timeout / error 时事件触发顺序
  1. 触发 xhr.onreadystatechange 事件,此时 readystate4
  2. 如果上传阶段还没有结束,则依次触发以下事件:

    • xhr.upload.onprogress
    • xhr.upload.[onabort 或 ontimeout 或 onerror]
    • xhr.upload.onloadend
  3. 触发 xhr.onprogress 事件
  4. 触发 xhr.[onabort 或 ontimeout 或 onerror] 事件
  5. 触发 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 使用指南

正文完
 0