Skip to content

第 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 来说,返回 404500 代码的响应是成功收到的响应!它只是包含错误代码。

正确的检查方法:

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 块。

巩固知识小测验

1. Fetch API 是...

2. 调用 `fetch(url)` 返回什么?

3. Promise 链中的 `.then()` 方法在什么时候被调用?

4. `response.json()` 方法用于...

5. 如何正确检查服务器是否没有返回错误(例如 404)?


🚀 本章总结:

你已经设置好了你的任务控制中心(ЦУП)的“主天线”,并学会了发送请求和接收响应。

  • 📡 你掌握了 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 资源的请求可能会被阻止。