1 基础

  1. 1. 创建一个对象
  2. var request = new XMLHttpRequest()
  3. 2. 监听请求成功后的状态变化
  4. request.onreadystatechange = function() {
  5. if (this.readyState == 4 && this.status == 200) {
  6. console.log(request.responseText)
  7. }
  8. };
  9. 第三行的 request.responseText 就是服务器返回的内容了(默认是字符串)
  10. 3. 设置请求参数,open并不会发送请求
  11. request.open("GET", "filename", true);
  12. 4. 发送(请求主体,如post请求),这个时候才是真正发送出去
  13. request.send(data || null);

第四步中,如果没有请求主体,必须设置为null,部分浏览器必须有。
参考下图axiose的设置

image.png

2 请求主体

参考:犀牛书18.1.3-编码请求主体
post请求要send(data),可以是简单的字符串,也可以是更复杂的数据( json / xml /file /blob)。

2.1 表单数据类型

content-type: application/x-www-form-urlencoded
html表单提交时,表单中的数据(每个元素的名和值)被编码到一个字符传中发送出去。
(浏览器表单提交的过程 参考: 高程3-14.4 表单序列化)
这种类型的编码方案相对简单,就是对key-value分别URL编码,并用&连接起来。

2.2 json数据类型

content-type: application/json
JS的JSON对象支持对json格式和普通js对象之间的转换,是目前主流的web交换格式。

2.3 xml数据类型

send()可以传入XML Document 对象。 ajax(async JavaScript and xml)中的x。
现在基本很少用了,但是可以用来描述复杂的数据格式。

2.3 FIle文件

html表单可以用来选择文件,并且将其放到请求体中,发送文件内容。
xhr对象没有选择文件的API,但是可以通过向send()中传入FIle对象来实现上传文件。
脚本只能获取用户通过 选择文件的File对象。元素有files属性,是存放File对象的类数组。

2.4 Blob对象

File对象只是Blob(二进制大数据对象块)的一个子类,send()容许传入任何Blob对象。
如果没有显示设置content-type,则会去Blob对象的type属性值
比如某次项目,新建和编辑是一个页面,存在上传图片功能,当新建以后,后端返回来是个base64图片地址,需要前端编辑完后,提交该字段还是个文件类型。
所以就需要把base64字符串转换成Blob

  1. let dataURIToBlob = (dataURI) => {
  2. const splitDataURI = dataURI.split(',')
  3. const byteString = splitDataURI[0].indexOf('base64') >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1])
  4. const mimeString = splitDataURI[0].split(':')[1].split(';')[0]
  5. const ia = new Uint8Array(byteString.length)
  6. for (let i = 0; i < byteString.length; i++)
  7. ia[i] = byteString.charCodeAt(i)
  8. return new Blob([ia], { type: mimeString })
  9. }

2.5 文件和其他数据同时存在

在form表单中,需要设置为muultiipart/form-data
在js中,新增了FormData 对象。可以多次调用append()把不同数据格式添加到对象中(可以是字符串、file、blob).同时还可以通过form表单预先设置。
把formData对象传递给send(),无需显示设置content-type,浏览器会自动设置。