fetch()
可以说是 XMLHttpRequest 的全面升级版(除了监听文件上传进度
),用于在 JavaScript 脚本里面发出 HTTP 请求。
1、基本使用
1.1 fetch的特点
fetch()
的功能与 XMLHttpRequest 基本相同,但有三个主要的差异。
(1)
fetch()
使用 Promise
(2)fetch()
采用模块化设计,API 分散在多个对象上(Response 对象、Request 对象、Headers 对象)
(3)fetch()
通过数据流(Stream 对象)处理数据,可以分块读取,有利于提高网站性能表现,减少内存占用,对于请求大文件或者网速慢的场景相当有用。
1.1 xhr与fetch的使用对比
fetch的使用
js
fetch('https://example.org/foo', {
method: 'POST',
mode: 'cors',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({ foo: 'bar' })
}).then(res => res.json()).then((res)=>console.log(res))
xhr使用
js
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://example.org/foo');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'json';
xhr.withCredentials = true;
xhr.onreadystatechange = function () {
// 请求完成
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.response)
}
}
};
xhr.send(JSON.stringify({ foo: 'bar' }))
1.3、两次Promise
js
// first await
let response = await fetch("/some-url")
// second await
let res = await response.json()
两个 await
的本质是:
- 获取响应头 (获取
Response
对象)。 - 等待响应体解析 (响应体可能很大,需要异步解析,因此需要第二个
await
)。
1.4、读取内容的方法
-
text(): 将响应体解析为纯文本字符串并返回。
-
json(): 将响应体解析为JSON格式并返回一个JavaScript对象。
-
blob(): 将响应体解析为二进制数据并返回一个Blob对象。
-
arrayBuffer(): 将响应体解析为二进制数据并返回一个ArrayBuffer对象。
-
formData(): 将响应体解析为FormData对象。
1.5、Response.body
Response.body
属性是 Response 对象暴露出的底层接口,返回一个 ReadableStream 对象
js
const response = await fetch('flower.jpg');
const reader = response.body.getReader();
while(true) {
const {done, value} = await reader.read();
if (done) {
break;
}
console.log(`Received ${value.length} bytes`)
}
1.6、Request header
js
let response = fetch(protectedUrl, {
headers: {
Authentication: 'secret'
}
});
1.7、其他配置(cache,mode,keepalive)
cache
cache
属性指定如何处理缓存。
no-store
:不缓存。no-cache
:优先协商缓存 mode
mode
属性指定请求的模式。可能的取值如下:
cors
:默认值,允许跨域请求。
keepalive
keepalive
属性用于页面卸载时,告诉浏览器在后台保持连接,继续发送数据。
一个典型的场景就是,用户离开网页时,脚本向服务器提交一些用户行为的统计信息。这时,如果不用keepalive
属性,数据可能无法发送,因为浏览器已经把页面卸载了。