介绍
曾经有一段时间,‘XMLHttpRequest’被用来编写API请求,它不包括承诺,也不使JavaScript代码变得干净。
现在,JavaScript有自己的内置方式来创建API请求,这是Fetch API,这是用Promises创建服务器请求的新标准,但它还包括其他功能。
在本教程中,您将使用 Fetch API 创建 GET 和 POST 请求。
前提条件
要完成本教程,您将需要以下内容:
- Node.js 的本地开发环境. Follow How to Install Node.js and Create a Local Development Environment.
- 在 JavaScript 中对编码的基本理解,您可以从 How to Code in JavaScript系列中了解更多。
步骤 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>
记住,作者
是以前创建的ul
的id
。
然后,创建一个列表
,这是一个 ‘文档片段’:
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
的变量,该变量将被设置为等于 createElement
用li
(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请求,您将包含url
和fetchData
作为您的fetch
POST请求的参数:
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()
的唯一参数,取代url
和fetchData
。
现在您知道使用 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)在这个主题上。