Fetch是一个新的,基于承诺的API,它允许我们执行Ajax请求,而无需与 XMLHttpRequest相关的所有烦恼。
接收请求
让我们通过从 JSONPlaceholder API 来演示一个简单的 GET 请求:
1fetch('https://jsonplaceholder.typicode.com/users')
2 .then(res => res.json())
3 .then(res => res.map(user => user.username))
4 .then(userNames => console.log(userNames));
输出将是一个用户名系列,如下:
1["Bret", "Antonette", "Samantha", "Karianne", "Kamren", "Leopoldo_Corkery", "Elwyn.Skiles", "Maxime_Nienow", "Delphine", "Moriah.Stanton"]
鉴于我们期望 JSON 响应,我们首先需要调用 json() 方法来将 Response 对象转化为我们可以互动的对象。
发布、放置和删除请求
若要创建除了 GET 以外的请求,请将一个对象作为第二个参数输入到接收呼叫中,其中包含要使用的方法以及所需的任何标题和请求的体:
1const myPost = {
2 title: 'A post about true facts',
3 body: '42',
4 userId: 2
5}
6
7const options = {
8 method: 'POST',
9 body: JSON.stringify(myPost),
10 headers: {
11 'Content-Type': 'application/json'
12 }
13};
14
15fetch('https://jsonplaceholder.typicode.com/posts', options)
16 .then(res => res.json())
17 .then(res => console.log(res));
JSONPlaceholder 将 POSTed 数据发送给我们,并附有一个 ID:
1Object {
2 body: 42,
3 id: 101,
4 title: "A post about true facts",
5 userId: 2
6}
<$>[注]您会注意到请求体必须是 stringified。
行为错误
当涉及到使用Fetch API的错误处理时,有捕获(pun intended 😉):如果请求正确击中终点并返回,则不会丢失任何错误,这意味着错误处理并不像链接捕获呼叫在您的捕获承诺链的末尾一样简单。
幸运的是,从接收呼叫的响应对象有一个OK属性,根据请求的成功情况将是 true 或 false. 如果 ok 是 false,则可以使用 Promise.reject():
1fetch('https://jsonplaceholder.typicode.com/postsZZZ', options)
2 .then(res => {
3 if (res.ok) {
4 return res.json();
5 } else {
6 return Promise.reject({ status: res.status, statusText: res.statusText });
7 }
8 })
9 .then(res => console.log(res))
10 .catch(err => console.log('Error, with message:', err.statusText));
使用上述示例,我们的承诺将被拒绝,因为我们正在调用一个不存在的终点。
1"Error, with message: Not Found"
Fetch + Async / 等待
由于Fetch是一个基于承诺的API,使用async函数是一个很好的选择,使您的代码更容易推理和同步看起来。
1async function fetchUsers(endpoint) {
2 const res = await fetch(endpoint);
3 let data = await res.json();
4
5 data = data.map(user => user.username);
6
7 console.log(data);
8}
9
10fetchUsers('https://jsonplaceholder.typicode.com/users');
或者,您可以从您的 async/Wait 函数返回一个承诺,然后您可以在呼叫函数后继续链接呼叫:
1async function fetchUsers(endpoint) {
2 const res = await fetch(endpoint);
3 const data = await res.json();
4
5 return data;
6}
7
8fetchUsers('https://jsonplaceholder.typicode.com/users')
9 .then(data => {
10 console.log(data.map(user => user.username));
11 });
调用 json() 返回承诺,所以在上面的示例中,当我们在 async 函数中返回数据
时,我们返回承诺。
然后再一次,如果答案的OK是假的,你也可以扔错误,并像通常一样在你的承诺链中捕捉错误:
1async function fetchUsers(endpoint) {
2 const res = await fetch(endpoint);
3
4 if (!res.ok) {
5 throw new Error(res.status); // 404
6 }
7
8 const data = await res.json();
9 return data;
10}
11
12fetchUsers('https://jsonplaceholder.typicode.com/usersZZZ')
13 .then(data => {
14 console.log(data.map(user => user.website));
15 })
16 .catch(err => console.log('Ooops, error', err.message));
1Ooops, error 404
多元化
- 如果您需要支持较旧的浏览器,例如 Internet Explorer 11,则需要使用 Fetch polyfill(如Github)(https://github.com/github/fetch)。
- 如果您需要在 Node.js中使用 Fetch,最流行的两种选项是 isomorphic-fetch和 node-fetch。
浏览器支持
Can I Use fetch?来自 caniuse.com 的主要浏览器中对 fetch 功能的支持数据。