如何使用 JavaScript Fetch API 获取数据

介绍

曾经有一段时间,‘XMLHttpRequest’被用来编写API请求,它不包括承诺,也不使JavaScript代码变得干净。

现在,JavaScript有自己的内置方式来创建API请求,这是Fetch API,这是用Promises创建服务器请求的新标准,但它还包括其他功能。

在本教程中,您将使用 Fetch API 创建 GET 和 POST 请求。

前提条件

要完成本教程,您将需要以下内容:

步骤 1 — 开始使用 Fetch API 语法

使用Fetch API的一种方法是通过fetch()作为参数传输API的URL:

1fetch(url)

fetch() 方法返回一个 Promise. 在fetch() 方法之后,包括 Promise 方法,然后():

1fetch(url)
2  .then(function() {
3    // handle the response
4  })

如果返回的承诺是解决,则在然后()方法中执行函数,该函数包含处理从API接收的数据的代码。

then() 方法之后,包括 catch() 方法:

1fetch(url)
2  .then(function() {
3    // handle the response
4  })
5  .catch(function() {
6    // handle the error
7  });

您使用fetch()调用的 API 可能已停用或可能出现其他错误。如果发生这种情况,将返回拒绝的承诺。使用捕获方法来处理拒绝

有了使用 Fetch API 的语法的理解,您现在可以继续在真实的 API 上使用 fetch()

步骤 2 — 使用 Fetch 从 API 获取数据

以下代码样本将基于 JSONPlaceholder API。 使用API,您将获得十个用户并使用JavaScript在页面上显示他们。

首先,创建一个HTML文件,并添加一个标题和未分类的列表,其中有作者id:

1[label authors.html]
2<h1>Authors</h1>
3<ul id="authors"></ul>

现在,将脚本标签添加到 HTML 文件的底部,并使用 DOM 选择器来抓取ul

1[label authors.html]
2<h1>Authors</h1>
3<ul id="authors"></ul>
4
5<script>
6  const ul = document.getElementById('authors');
7</script>

记住,作者是以前创建的ulid

然后,创建一个列表,这是一个 ‘文档片段’:

1[label authors.html]
2<script>
3  // ...
4
5  const list = document.createDocumentFragment();
6</script>

所有附加的列表项目都将添加到列表文档片段不是活跃文档树结构的一部分。

创建一个名为url的常态变量,该变量将包含返回十个随机用户的API URL:

1[label authors.html]
2<script>
3  // ...
4
5  const url = 'https://jsonplaceholder.typicode.com/users';
6</script>

现在使用 Fetch API,将使用fetch()url作为参数的 JSONPlaceholder API 调用:

1[label authors.html]
2<script>
3  // ...
4
5  fetch(url)
6</script>

您正在调用 Fetch API 并将 URL 传输到 JSONPlaceholder API. 然后收到响应. 但是,您得到的响应不是 JSON,而是可以使用一系列方法的对象,这取决于您想要用信息做什么。

添加then()方法,该方法将包含一个称为响应的参数的函数:

1[label authors.html]
2<script>
3  // ...
4
5  fetch(url)
6    .then((response) => {})
7</script>

响应参数取决于从fetch(url)返回的对象的值. 使用json()方法将响应转换为 JSON 数据:

1[label authors.html]
2<script>
3  // ...
4
5  fetch(url)
6    .then((response) => {
7      return response.json();
8    })
9</script>

还需要处理 JSON 数据. 添加另一个 then() 语句,其中包含一个名为 `data' 的函数:

 1[label authors.html]
 2<script>
 3  // ...
 4
 5  fetch(url)
 6    .then((response) => {
 7      return response.json();
 8    })
 9    .then((data) => {})
10</script>

在此函数中,创建一个名为作者的变量,该变量设置为等于数据:

 1[label authors.html]
 2<script>
 3  // ...
 4
 5  fetch(url)
 6    .then((response) => {
 7      return response.json();
 8    })
 9    .then((data) => {
10      let authors = data;
11    })
12</script>

对于作者中的每个作者,您将想要创建一个列表项目,显示他们的名字。

 1[label authors.html]
 2<script>
 3  // ...
 4
 5  fetch(url)
 6    .then((response) => {
 7      return response.json();
 8    })
 9    .then((data) => {
10      let authors = data;
11
12      authors.map(function(author) {
13
14      });
15    })
16</script>

在你的地图函数中,创建一个名为li的变量,该变量将被设置为等于 createElementli (HTML元素)作为参数。

 1[label authors.html]
 2<script>
 3  // ...
 4
 5  fetch(url)
 6    .then((response) => {
 7      return response.json();
 8    })
 9    .then((data) => {
10      let authors = data;
11
12      authors.map(function(author) {
13        let li = document.createElement('li');
14        let name = document.createElement('h2');
15        let email = document.createElement('span');
16      });
17    })
18</script>

h2元素将包含作者名称span元素将包含作者的电子邮件。

 1[label authors.html]
 2<script>
 3  // ...
 4
 5  fetch(url)
 6    .then((response) => {
 7      return response.json();
 8    })
 9    .then((data) => {
10      let authors = data;
11
12      authors.map(function(author) {
13        let li = document.createElement('li');
14        let name = document.createElement('h2');
15        let email = document.createElement('span');
16
17        name.innerHTML = `${author.name}`;
18        email.innerHTML = `${author.email}`;
19      });
20    })
21</script>

接下来,将这些 DOM 元素连接到 appendChild:

 1[label authors.html]
 2<script>
 3  // ...
 4
 5  fetch(url)
 6    .then((response) => {
 7      return response.json();
 8    })
 9    .then((data) => {
10      let authors = data;
11
12      authors.map(function(author) {
13        let li = document.createElement('li');
14        let name = document.createElement('h2');
15        let email = document.createElement('span');
16
17        name.innerHTML = `${author.name}`;
18        email.innerHTML = `${author.email}`;
19
20        li.appendChild(name);
21        li.appendChild(email);
22        list.appendChild(li);
23      });
24    })
25
26  ul.appendChild(list);
27</script>

请注意,每个列表项目都被附加到文档片段``列表中,一旦地图完成,则列表被附加到ul未分类的列表元素中。

当两个then()函数完成时,您现在可以添加catch()函数,该函数将记录潜在的错误到控制台:

 1[label authors.html]
 2<script>
 3  // ...
 4
 5  fetch(url)
 6    .then((response) => {
 7      // ...
 8    })
 9    .then((data) => {
10      // ...
11    })
12    .catch(function(error) {
13      console.log(error);
14    });
15
16  // ...
17</script>

以下是您创建的请求的完整代码:

 1[label authors.html]
 2<h1>Authors</h1>
 3<ul id="authors"></ul>
 4
 5<script>
 6  const ul = document.getElementById('authors');
 7  const list = document.createDocumentFragment();
 8  const url = 'https://jsonplaceholder.typicode.com/users';
 9
10  fetch(url)
11    .then((response) => {
12      return response.json();
13    })
14    .then((data) => {
15      let authors = data;
16
17      authors.map(function(author) {
18        let li = document.createElement('li');
19        let name = document.createElement('h2');
20        let email = document.createElement('span');
21
22        name.innerHTML = `${author.name}`;
23        email.innerHTML = `${author.email}`;
24
25        li.appendChild(name);
26        li.appendChild(email);
27        list.appendChild(li);
28      });
29    }).
30    .catch(function(error) {
31      console.log(error);
32    });
33
34  ul.appendChild(list);
35</script>

您刚刚使用 JSONPlaceholder API 和 Fetch API 成功执行了 GET 请求,在下一步,您将执行 POST 请求。

步骤 3 – 处理 POST 请求

默认回收到 GET 请求,但您可以使用所有其他类型的请求,更改标题,并发送数据。

首先,包括持有链接到 JSONPlaceholder API 的常数变量:

1[label new-author.js]
2const url = 'https://jsonplaceholder.typicode.com/users';

接下来,你需要设置你的对象,并将其传递为收集函数的第二个参数. 这将是一个名为数据的对象,其键为名称和值为Sammy(或你的名字):

1[label new-author.js]
2// ...
3
4let data = {
5  name: 'Sammy'
6}

由于这是一个 POST 请求,您将需要明确表示。创建一个名为 `fetchData’ 的对象:

1[label new-author.js]
2// ...
3
4let fetchData = {
5
6}

此对象需要包含三个键:方法,身体标题:

 1[label new-author.js]
 2// ...
 3
 4let fetchData = {
 5  method: 'POST',
 6  body: JSON.stringify(data),
 7  headers: new Headers({
 8    'Content-Type': 'application/json; charset=UTF-8'
 9  })
10}

方法键将具有POST值。body将设置为刚刚创建的数据对象的JSON.stringify()(https://andsky.com/tech/tutorials/how-to-work-with-json-in-javascript)格式。

Headers接口是Fetch API的属性,它允许您对HTTP请求和响应标题执行操作. 这篇名为How To Define Routes and HTTP Request Methods in Express(https://andsky.com/tech/tutorials/nodejs-express-routing)的文章可以为您提供更多信息。

有了这个代码,可以使用Fetch API进行POST请求,您将包含urlfetchData作为您的fetchPOST请求的参数:

1[label new-author.js]
2// ...
3
4fetch(url, fetchData)

然后()函数将包含处理从 JSONPlaceholder API 接收的响应的代码:

1[label new-author.js]
2// ...
3
4fetch(url, fetchData)
5  .then(function() {
6    // Handle response you get from the API
7  });

以下是您创建的请求的完整代码:

 1[label new-author.js]
 2const url = 'https://jsonplaceholder.typicode.com/users';
 3
 4let data = {
 5  name: 'Sammy'
 6}
 7
 8let fetchData = {
 9  method: 'POST',
10  body: JSON.stringify(data),
11  headers: new Headers({
12    'Content-Type': 'application/json; charset=UTF-8'
13  })
14}
15
16fetch(url, fetchData)
17  .then(function() {
18    // Handle response you get from the API
19  });

或者,您可以将 fetch() 传递给一个 Request对象。

 1[label new-author-request.js]
 2const url = 'https://jsonplaceholder.typicode.com/users';
 3
 4let data = {
 5  name: 'Sammy'
 6}
 7
 8let request = new Request(url, {
 9  method: 'POST',
10  body: JSON.stringify(data),
11  headers: new Headers({
12    'Content-Type': 'application/json; charset=UTF-8'
13  })
14});
15
16fetch(request)
17  .then(function() {
18    // Handle response you get from the API
19  });

通过这种方法,请求可以用作fetch()的唯一参数,取代urlfetchData

现在您知道使用 Fetch API 创建和执行 POST 请求的两种方法。

结论

虽然Fetch API尚未被所有浏览器支持,但它是XMLHttpRequest的绝佳替代品。

如果您想了解如何使用 React 调用 Web API,请查看本文(https://andsky.com/tech/tutorials/how-to-call-web-apis-with-the-useeffect-hook-in-react)在这个主题上。

Published At
Categories with 技术
comments powered by Disqus