Fetch API 介绍
基本用法
fetch() 与 经典的 XMLHttpRequest 基本相同,但有以下三个差异
- fetch 使用 Promise,不使用回调函数,更加符合现代编码式样
- fetch 采用模块化设计,API分散在多个对象上,Response、Request、Headers,相比 XMLHttpRequest 设计更合理
- fetch 通过数据流 Stream 处理数据,可以分块读取,减少内存占用,而 XMLHttpRequest 不支持数据流,所有数据必须放在缓存里,必须要全部获取后再一次读出来
1 | fetch('https://api.github.com/users/ruanyf') |
上面示例中,fetch 接收到的 response 是一个 Stream 对象,response.json()是一个异步操作,取出所有内容,并将其转为 JSON 对象
Response 对象
fetch 请求成功以后,得到的是一个 Response 对象。它对应服务器的 HTTP 回应。
前面说过,Response 包含的数据通过 Stream 接口异步读取,但是它还包含一些同步属性,对应 HTTP 回应的标头信息(Headers),可以立即读取。
- Response.ok属性返回一个布尔值,表示请求是否成功,true对应 HTTP 请求的状态码 200 到 299,false对应其他的状态码。
- Response.status属性返回一个数字,表示 HTTP 回应的状态码(例如200,表示成功请求)
- Response.statusText属性返回一个字符串,表示 HTTP 回应的状态信息(例如请求成功以后,服务器返回”OK”)
fetch()发出请求以后,有一个很重要的注意点:只有网络错误,或者无法连接时,fetch()才会报错,其他情况都不会报错,而是认为请求成功。
这就是说,即使服务器返回的状态码是 4xx 或 5xx,fetch()也不会报错(即 Promise 不会变为 rejected状态)。
只有通过Response.status属性,得到 HTTP 回应的真实状态码,才能判断请求是否成功。
读取内容的办法
Response对象根据服务器返回的不同类型的数据,提供了不同的读取方法
- response.text():得到文本字符串
- response.json():得到 JSON 对象
- response.blob():得到二进制 Blob 对象
- response.formData():得到 FormData 表单对象
- response.arrayBuffer():得到二进制 ArrayBuffer 对象
上面5个读取方法都是异步的,返回的都是 Promise 对象。必须等到异步操作结束,才能得到服务器返回的完整数据
response.blob()
response.blob()用于获取二进制文件
1 | const response = await fetch('flower.jpg'); |
response.arrayBuffer()
response.arrayBuffer()主要用于获取流媒体文件
1 | const audioCtx = new window.AudioContext(); |
定制请求
fetch()的第一个参数是 URL,还可以接受第二个参数,作为配置对象,定制发出的 HTTP 请求
1 | fetch(url, optionObj) |
optionObj 配置对象用到了三个属性
- method:HTTP 请求的方法,POST、DELETE、PUT都在这个属性设置
- headers:一个对象,用来定制 HTTP 请求的标头
- body:POST 请求的数据体
提交JSON
标头Content-Type要设成’application/json;charset=utf-8’。因为默认发送的是纯文本,Content-Type的默认值是’text/plain;charset=UTF-8’
1 | const user = { name: 'John', surname: 'Smith' }; |
提交表单
1 | const form = document.querySelector('form'); |
文件上传
1 | const input = document.querySelector('input[type="file"]'); |
直接上传二进制
1 | let blob = await new Promise(resolve => |
取消 fetch 请求
fetch()请求发送以后,如果中途想要取消,需要使用AbortController对象
1 | let controller = new AbortController(); |