第 4.1 章:Fetch API 基础
学习时间: 45 分钟
1. Fetch API:“任务控制中心”的主天线
想象一下,你的飞行任务控制中心(ЦУП)拥有一根巨大的无线电天线,用于与航天器通信。你可以将其调谐到所需的频率,发送指令并等待响应。
Fetch API 就是现代浏览器中这样一种“内置天线”。它是 JavaScript 用于向服务器执行 HTTP 请求的标准接口。它允许:
- 📡 向我们的 API 发送“指令”(GET、POST、PUT、DELETE)。
- 🛰️ 从服务器接收“遥测数据”(JSON 数据)。
- ⚙️ 异步工作,在等待响应时不会“冻结”用户界面。
💡 太空类比:
fetch()
命令就像是“天线,建立连接!”。你向它传递:
- 目标坐标(我们 API 的 URL)。
- 指令类型(方法:GET、POST)。
- 指令内容(请求体、请求头)。
作为响应,你不会立即收到数据本身,而是收到一个承诺 (Promise),即数据将会到来。
2. 异步:光速通信
与遥远的航天器通信需要时间。你不能仅仅暂停任务控制中心的所有工作,然后等待响应到来。你发送指令并继续工作,当响应到达时,系统会通知你。
这就是异步。JavaScript 在等待服务器响应时不会阻塞其他代码的执行。为了管理这个过程,Fetch API 使用了承诺 (Promises)。
承诺 (Promise) 是你发送请求的“收据”。它有三种状态:
pending
(待定): 信号仍在途中。fulfilled
(已完成): 成功收到响应!rejected
(已拒绝): 发生了错误(例如,没有连接)。
3. 第一个请求:了解国际空间站的位置
让我们使用 fetch
发送我们的第一个请求。我们将使用一个简单的 HTML 文件和 <script>
标签。
步骤 1:创建 index.html
在一个新文件夹中(例如,frontend_fleet_control
)创建一个 index.html
文件。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>任务控制中心 - Fetch API</title>
</head>
<body>
<h1>国际空间站通信状态</h1>
<div id="iss-status">等待数据...</div>
<script>
// 我们的 JavaScript 代码将在这里
</script>
</body>
</html>
步骤 2:编写 fetch
代码
在 <script>
标签内部,添加我们对 Open Notify 公共 API 的第一个 fetch
请求。
// index.html -> <script>
const issApiUrl = 'http://api.open-notify.org/iss-now.json';
const statusDiv = document.getElementById('iss-status');
console.log('正在发送请求以获取国际空间站坐标...');
fetch(issApiUrl)
.then(response => {
// 第一个 .then() 处理 HTTP 响应本身
console.log('已从服务器收到响应!', response);
// 将响应体转换为 JSON,这也是一个异步操作
return response.json();
})
.then(data => {
// 第二个 .then() 获取已解析的 JSON 数据
console.log('数据已成功转换为 JSON!', data);
const position = data.iss_position;
statusDiv.innerHTML = `国际空间站当前位于此处:
<strong>纬度:</strong> ${position.latitude},
<strong>经度:</strong> ${position.longitude}`;
})
.catch(error => {
// .catch() 将在发生网络错误时触发
console.error('与国际空间站通信错误!', error);
statusDiv.textContent = '未能获取数据。请检查连接。';
});
fetch(url)
: 发送 GET 请求。返回一个 Promise。.then(callback)
: 当 Promise 成功解决(fulfilled
)时执行。第一个.then
接收一个Response
对象。response.json()
: 读取响应体并将其解析为 JSON 的方法。它也返回一个 Promise!.catch(callback)
: 当 Promise 被拒绝(rejected
)时执行,例如由于网络错误。
步骤 3:在浏览器中打开
只需在浏览器中打开 index.html
文件。你应该会看到“等待数据...”变为国际空间站的当前坐标。打开开发者控制台(F12)以查看日志。
4. “如果……”:服务器错误处理
如果我们请求一个不存在的 URL 会怎样?
fetch('http://api.open-notify.org/non-existent-endpoint')
Fetch 的设计是,.catch()
只会在网络错误(无互联网连接、DNS 未找到)时触发。但是,对于 fetch
来说,返回 404
或 500
代码的响应是成功收到的响应!它只是包含错误代码。
正确的检查方法:
fetch('http://api.open-notify.org/non-existent-endpoint')
.then(response => {
// 检查 .ok 属性,对于 200-299 状态码,它为 true
if (!response.ok) {
// 如果响应不是“OK”,则创建自己的错误以进入 .catch()
throw new Error(`HTTP 错误!状态码:${response.status}`);
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('执行请求时发生错误:', error);
});
response.ok
:这是你主要的成功指示器。throw new Error()
:我们手动“中断”Promise 链,以进入.catch
块。
巩固知识小测验
🚀 本章总结:
你已经设置好了你的任务控制中心(ЦУП)的“主天线”,并学会了发送请求和接收响应。
- 📡 你掌握了
fetch()
的基本语法。 - 🛰️ 理解了什么是承诺 (Promises) 以及如何使用
.then()
和.catch()
。 - ⚙️ 学会了通过检查
response.ok
来正确处理服务器响应。
连接已建立! 在下一章中,我们将把我们的任务控制中心连接到我们使用 FastAPI 创建的太空舰队 API,并学习如何获取和显示我们的飞船列表。
📌 检查:
- 确保你的
index.html
文件正确显示国际空间站的坐标。- 尝试故意破坏 URL,并在开发者控制台中查看会输出什么错误。
⚠️ 如果代码不工作:
- CORS 错误: 如果你尝试从一个以
file:///...
方式打开的文件向你的本地 FastAPI API(例如http://127.0.0.1:8000
)发送请求,浏览器会因为 CORS 安全策略而阻止该请求。我们将在下一章中解决这个问题。目前我们使用的是允许这种操作的公共 API。- HTTP/HTTPS:
http://api.open-notify.org
通过 HTTP 工作。一些浏览器可能会对此发出警告。如果你从 HTTPS 网站操作,对 HTTP 资源的请求可能会被阻止。