Skip to content

HTTP API 请求

This content is not available in your language yet.

API

APIApplication Programming Interface 的缩写,即应用程序编程接口。它的范围很广泛,一个库的接口,例如我们之前介绍过的 React 的接口就可以被称之为 API。但是在这里,我们想要详细讨论的是 API 的一个细分类 HTTP API

HTTP API 是一种通过 HTTP 协议来提供服务的接口。你可以简单的把 HTTP 协议理解为你日常使用的浏览器访问网页时使用的协议。HTTP API 则可以理解为一种特殊的网页,它不是用来展示给用户看的,而是用来提供数据给程序使用的。

打个比方,我有一个 HTTP API,它的地址是 https://api.example.com,我可以通过访问这个地址来获取一些数据,例如 https://api.example.com/user 可以获取用户信息,https://api.example.com/post 可以获取文章信息。这些地址就是 APIendpoint,通过访问这些地址,我们可以获取到对应的数据。

在使用 HTTP API 的时候,我们会使用不同的 请求方法 比如说 GET 用来获取数据,POST 用来提交数据,PUT 用来更新数据,DELETE 用来删除数据。这些请求方法就是我们和 API 交互的方式。虽然你可以把所有功能都使用 GET 方法来实现,但是这样会让你的 API 变得不够规范,不够清晰。所以在使用 API 的时候,我们应该根据 HTTP 协议的规范来使用对应的请求方法,而这一套规范被称之为 Rest API

现在,让我们整理一下我们学到的东西。为了发起一个 HTTP API 请求,我们需要知道以下几个信息:

  • API 的地址,被称之为 endpoint,如 https://api.example.com/user
  • 请求方法,如 GETPOSTPUTDELETE
  • 请求内容,比如说 name = 'John'

在发起请求后,我们会得到一个 response,这个 response 包含了我们请求的数据,在这个例子中,他可能是一个用户的信息,比如说 age = 18

现在,你可能注意到了上面的例子中 name = 'John' age = 18 都是字符串,他们的格式不清晰,在数据变得更加庞大的时候,这种格式会变得难以维护。所以我们需要一种更加规范的数据格式,这就是 JSON。有关 JSON 的概念可以在这个课程的 基础工具和概念 部分找到。在这里,我们就可以修改成请求内容为 {"name": "John"},返回内容为 {"age": 18}。这样的格式更加清晰,更加容易维护。

现在,让我们专注于使用 HTTP API,至于如何制作一个 HTTP API 则是后端的工作,这会在下一个章节中介绍。

发起一个请求

其实,最贱的 GET 请求就是在浏览器中输入一个地址,然后按下回车。比如说,你可以打开这门课程提供的 DEMO API https://junxuanb.com/api/products.json 这样你就已经发起了一个 GET 请求,你会得到一个 JSON 格式的数据。但是,当你想要发起更加复杂的请求,例如 POSTPUTDELETE 的时候,你就需要使用一些工具来帮助你发起请求。

市面上有很多调试工具,例如 postmanApifox,这些工具都可以帮助你发起 HTTP API 请求。你可以自己尝试,寻找一个适合你的工具并且尝试向 https://jsonplaceholder.typicode.com/posts 发送一个 POST 请求。

注意,这是一个 POST 请求,你看到的内容应该是:

{
"id": 101
}

如果你获得了这个结果,那么恭喜你,你已经成功发起了一个 POST 请求。否则,你发送的可能是 GET 请求。接下来我们将会学习如何在我们的程序中使用 HTTP API

useEffect

首先,我们需要介绍一个东西叫做 useEffectuseEffect 是一个 React 提供的 hook,它可以让我们在 React 组件中执行一些副作用操作,比如说发起一个 HTTP API 请求。换一句话就是,当我们要执行某个操作,它会花费不少的时间并且不影响用户看到的大框架时,我们就可以使用 useEffect 来执行这个操作。比如说,我现在要展示用户钱包的余额,那么因为获取余额信息需要花费时间,并且余额不会影响展示的大框架,所以我就可以使用 useEffect 来获取余额信息。

让我们回到 HelloWorld.tsx 在 HelloWord 组件内的 return 之前插入一个 useEffect

useEffect(() => {
// 获取信息
}, []);

让我来解释一下这段代码,这里的 useEffect 接受两个参数,第一个参数是一个函数,这个函数就是我们要执行的操作,第二个参数是一个数组,这个数组是一个依赖数组,当数组中的值发生变化时,useEffect 会重新执行。在这个例子中,我们传入了一个空数组,这意味着 useEffect 只会在组件挂载时执行一次。对于第二个数组举个例子,如果我们的页面中有一个文本框用于输入银行卡号,另一个文字框用来展示对应的余额。那么我们就可以把银行卡号的值放入依赖数组中,这样当银行卡号发生变化时,useEffect 就会重新执行,获取对应的余额。

在 TS 中使用 Axios 发起请求

接下来,让我们补充 // 获取信息 部分的代码。在这里,我们的目标是展示一个水果列表,我们可以通过 https://junxuanb.com/api/products.json 来获取这个列表。接下来让我们逐步实现。

首先,我们需要用到 Axios,这是一个用于发起 HTTP API 请求的库,它提供了一种简单的方式来发起请求。首先,你需要用 npm 安装 Axios

Terminal window
npm install axios

然后,让我们先新建一个空白的 state 来存储我们获取到的水果列表。还记得我们之前提到过的 useState 吗?让我们使用它来创建一个 state

const [products, setProducts] = useState<
{
id: number,
name: string,
price: number
}[]
>([]);

这里的 products 是我们的水果列表,setProducts 是一个函数,用来更新 products 的值。<>内的东西是水果列表的格式。接下来,我们就可以使用 Axios 来获取水果列表了:

axios.get('https://junxuanb.com/api/products.json')
.then(response => {
setProducts(response.data.products);
});

注意我们需要使用 import axios from 'axios'; 来引入 Axios。在这段代码中,我们首先使用 axios.get 来发起一个 GET 请求,然后我们使用 .then 来填入获取到数据后的操作。response.data 可以用于获取到数据,查看过 https://junxuanb.com/api/products.json 你会发现 products 是一个数组,所以我们可以直接使用 response.data.products 来获取到水果列表。最后,我们使用 setProducts 来更新 products 的值。

现在,我们就能获取到数据了!我们希望按照 #[id] - [name] - $[price] 的格式展示水果列表,所以我们需要对 products 进行处理:

<div>
{products.map(product => (
<div key={product.id}>
{product.id} - {product.name} - ${product.price}
</div>
))}
</div>

这里,我们使用 products.map 来遍历 products,然后使用 product.idproduct.nameproduct.price 来展示水果列表。key={product.id} 是为了让 React 能够更好的识别每个水果,这样可以提高性能。现在,你就应该在你的网页上看到这个内容:

1 - Apple - $1.99
2 - Banana - $0.99
3 - Cherry - $2.99

如果你遇到了问题,你可以参考我的 HelloWorld.tsx

// ...
import axios from "axios";
const HelloWorld = () => {
// ...
const [products, setProducts] = useState<
{
id: number,
name: string,
price: number
}[]
>([]);
useEffect(() => {
axios.get('https://junxuanb.com/api/products.json')
.then(response => {
setProducts(response.data.products);
});
}, []);
return (
<Flex vertical gap={'middle'}>
<div>
{products.map(product => (
<div key={product.id}>
{product.id} - {product.name} - ${product.price}
</div>
))}
</div>
{/* ... */}
</Flex>
)
}
export default HelloWorld
点击查看答案

进阶操作

现在,你已经学会了如何使用 Axios 来发起 HTTP API 请求,但是这只是冰山一角。让我们学习一些进阶操作。

发起 POST 请求

类似的,我们可以使用 axios.post 来发起 POST 请求,包含一个简单的 JSON。让我们尝试向 https://jsonplaceholder.typicode.com/posts 发送一个 POST 请求:

useEffect(() => {
axios.post('https://jsonplaceholder.typicode.com/posts', {
name: 'Orange',
price: 1.49
})
.then(response => {
console.log(response.data);
});
}, []);

现在,打开你的控制台(在你的网页上任意位置右键点击 检查 即可打开调试面板,上面的选项中找到 控制台),你应该看到了一个 POST 请求的结果:

{
"name": "Orange",
"price": 1.49,
"id": 101
}

axios 根域名

在实际开发中,我们基本上以使用自己的后端 API 为主,所以部分域名是固定的,比如说 https://junxuanb.com/api/,这时候我们可以使用 axios.create 来创建一个 axios 实例,这样我们就不需要在每次请求时都写上 https://junxuanb.com/api/

现在,让我们在 src 目录下新建一个 axios.ts 文件:

import axios from "axios";
const myAPI = axios.create({
baseURL: "https://junxuanb.com/api/",
});

这样,我们就完成了一个 axios 实例的创建,现在我们就可以使用 axiosInstance.get('products.json') 来代替 axios.get('https://junxuanb.com/api/products.json')。让我们来修改 HelloWorld.tsx

import myAPI from "../axios";
useEffect(() => {
myAPI.get('products.json')
.then(response => {
setProducts(response.data.products);
});
}, []);

现在代码就变得更加简洁了!

结语

现在,你已经学会了最基础的前端开发内容,接下来,学习如何使用 React 来制作一个简单的购物车吧!