Skip to content

第6.1章:将FastAPI与前端连接

学习时间: 30分钟


1. 回归“超光速引擎”:协议比较

在上一章中,我们将任务控制中心(前端)与“国际空间站”(Laravel API)成功对接。现在,我们将回到我们的超光速战斗机(FastAPI),并执行相同的操作。

本章的目标不仅仅是重复操作,而是比较两种方法。这就像同一艘龙飞船,先与国际空间站对接,然后与中国空间站“天宫”对接。对接接口相同(REST),但在程序和端口位置上可能会有细微差别。

💡 宇宙类比:

过程相同:靠近、对齐、对接。但对于“国际空间站”,需要使用 /api/planets 端口,而对于“天宫”,则需要使用 /spaceships 端口。我们任务控制中心的操作员必须了解这些细节,才能确保任务成功。


2. 准备“战斗机”(FastAPI)进行对接

我们已在第4.2章中完成此操作,但让我们确保一切就绪。

步骤1:启动FastAPI服务器

  1. 如果Laravel服务器正在运行,请将其停止(以避免端口冲突)。
  2. 在你的FastAPI项目文件夹中打开终端。
  3. 激活虚拟环境:

    • Windows: .\venv\Scripts\Activate.ps1
    • macOS / Linux: source venv/bin/activate
  4. 启动服务器:

    uvicorn main:app --reload
    
    服务器将通过 http://127.0.0.1:8000 地址访问。

步骤2:检查 main.py 中的CORS设置

确保你的FastAPI项目中配置了我们之前添加的 CORSMiddleware。它应该允许来自前端地址的请求。

# main.py
from fastapi.middleware.cors import CORSMiddleware

# ...

origins = [
    "http://127.0.0.1:5500", # Live Server地址
    "null", # 用于 file:///
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# ...
如果一切就绪,你的FastAPI服务器已完全准备好。


3. 将任务控制中心的“天线”重新指向FastAPI

现在最有趣的部分来了——我们需要对JavaScript进行最小的更改,使其再次与FastAPI协同工作。

步骤1:更改基础URL

打开 api.js 并将 API_BASE_URL 恢复为其初始值。

// api.js

// 指定我们的FastAPI API的URL
const API_BASE_URL = 'http://127.0.0.1:8000'; // <-- 不带 /api!

// ... apiRequest 的其余代码 ...

步骤2:适应FastAPI的响应结构

回想一下,我们的FastAPI中的 GET /spaceships 返回的是一个简单数组,而不是一个带分页的对象。这意味着我们需要将 fetchAndDisplayFleet 代码恢复到其原始状态。

修改 app.js 中的 fetchAndDisplayFleet 函数:

// app.js

async function fetchAndDisplayFleet() {
    try {
        fleetListContainer.innerHTML = '<p>正在从FastAPI加载遥测数据...</p>';
        const ships = await apiRequest('/spaceships'); // <-- 请求 /spaceships

        // 在FastAPI中,我们有一个简单数组,因此不需要 .data 键!

        fleetListContainer.innerHTML = '';
        if (ships.length === 0) {
            fleetListContainer.innerHTML = '<p>注册表中没有设备。</p>';
            return;
        }

        ships.forEach(ship => {
            // 恢复我们原始的创建卡片函数
            const card = createShipCard(ship);
            fleetListContainer.appendChild(card);
        });
    } catch (error) {
        fleetListContainer.innerHTML = `<p style="color: #ff6b6b;">舰队加载错误:${error.message}</p>`;
    }
}

// 创建飞船卡片的原始函数
function createShipCard(ship) {
    const card = document.createElement('div');
    card.className = 'card';
    card.innerHTML = `
        <h3>${ship.name} (ID: ${ship.id})</h3>
        <p>类型: ${ship.type}</p>
        <p>发射年份: ${ship.launch_year}</p>
        <p>状态: ${ship.status}</p>
        <div class="card-actions">
            <button class="edit-btn" data-ship-id="${ship.id}">修改</button>
            <button class="delete-btn" data-ship-id="${ship.id}">报废</button>
        </div>
    `;
    return card;
}

步骤3:CRUD操作检查

由于FastAPI中的Pydantic模型和HTML表单中的字段(nametypelaunch_yearstatus)是匹配的,handleSaveShiphandleDeleteShip 函数应该无需更改即可工作,因为它们已经指向 /spaceships 端点。


4. 比较总结:这对前端开发者意味着什么?

  • REST的通用性: 你亲身验证了,如果遵循REST原则,前端对于后端是用什么语言编写(PHP/Laravel还是Python/FastAPI)并不重要。
  • 文档的重要性: 主要区别在于端点URLJSON响应结构。这正是API文档中应该描述的内容。没有文档,前端开发者将“盲目”工作。
  • 前端的灵活性: 你的JavaScript代码应该足够灵活,以便轻松适应不同的数据格式(例如,检查是否存在 data 键,或者它只是一个简单数组)。

结论: 使用REST API的技能是一把通用钥匙,它能打开与任何现代后端交互的大门。


巩固知识小测验

1. 我们的Laravel API和FastAPI API之间URL的主要区别在于...

2. 从Laravel的分页响应切换到FastAPI的简单数组时,JS代码需要进行哪些主要更改?

3. 这项实验证明,对于前端开发者来说...

4. CORS的配置是...

5. 如果FastAPI也像Laravel一样使用分页,前端需要做什么?


🚀 本章总结:

你成功切换了任务控制中心的“通信协议”,并实践比较了与两种不同后端系统的工作。

  • ✅ 你巩固了调整 API_BASE_URL 以在服务器之间切换的技能。
  • ✅ 你理解了响应结构(data 与简单数组)的重要性以及如何使前端适应它。
  • ✅ 你意识到一名优秀的前端开发者应该准备好处理任何RESTful API,并仔细研究其文档。

通用对接技能已获得! 现在我们已经掌握了基本连接的设置,是时候讨论更复杂的协议了——CORS、身份验证和安全性。

📌 检查点:

  • 确保你的FastAPI服务器正在运行。
  • 确保你已将 API_BASE_URLapp.js 中的响应处理逻辑恢复到FastAPI版本。
  • 检查你的前端是否再次正确执行与FastAPI后端的所有CRUD操作。

⚠️ 如果出现错误:

  • CORS error: 确保FastAPI服务器以正确的CORS设置运行。
  • 错误 Cannot read properties of undefined (reading 'length') 你可能忘记从 responseData 中移除 .data 的访问。
  • 404 Not Found: 检查 API_BASE_URL —— FastAPI没有 /api 前缀。