第6.1章:将FastAPI与前端连接
学习时间: 30分钟
1. 回归“超光速引擎”:协议比较
在上一章中,我们将任务控制中心(前端)与“国际空间站”(Laravel API)成功对接。现在,我们将回到我们的超光速战斗机(FastAPI),并执行相同的操作。
本章的目标不仅仅是重复操作,而是比较两种方法。这就像同一艘龙飞船,先与国际空间站对接,然后与中国空间站“天宫”对接。对接接口相同(REST),但在程序和端口位置上可能会有细微差别。
💡 宇宙类比:
过程相同:靠近、对齐、对接。但对于“国际空间站”,需要使用
/api/planets
端口,而对于“天宫”,则需要使用/spaceships
端口。我们任务控制中心的操作员必须了解这些细节,才能确保任务成功。
2. 准备“战斗机”(FastAPI)进行对接
我们已在第4.2章中完成此操作,但让我们确保一切就绪。
步骤1:启动FastAPI服务器
- 如果Laravel服务器正在运行,请将其停止(以避免端口冲突)。
- 在你的FastAPI项目文件夹中打开终端。
-
激活虚拟环境:
- Windows:
.\venv\Scripts\Activate.ps1
- macOS / Linux:
source venv/bin/activate
- Windows:
-
启动服务器:
服务器将通过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=["*"],
)
# ...
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表单中的字段(name
、type
、launch_year
、status
)是匹配的,handleSaveShip
和 handleDeleteShip
函数应该无需更改即可工作,因为它们已经指向 /spaceships
端点。
4. 比较总结:这对前端开发者意味着什么?
- REST的通用性: 你亲身验证了,如果遵循REST原则,前端对于后端是用什么语言编写(PHP/Laravel还是Python/FastAPI)并不重要。
- 文档的重要性: 主要区别在于端点URL和JSON响应结构。这正是API文档中应该描述的内容。没有文档,前端开发者将“盲目”工作。
- 前端的灵活性: 你的JavaScript代码应该足够灵活,以便轻松适应不同的数据格式(例如,检查是否存在
data
键,或者它只是一个简单数组)。
结论: 使用REST API的技能是一把通用钥匙,它能打开与任何现代后端交互的大门。
巩固知识小测验
🚀 本章总结:
你成功切换了任务控制中心的“通信协议”,并实践比较了与两种不同后端系统的工作。
- ✅ 你巩固了调整
API_BASE_URL
以在服务器之间切换的技能。 - ✅ 你理解了响应结构(
data
与简单数组)的重要性以及如何使前端适应它。 - ✅ 你意识到一名优秀的前端开发者应该准备好处理任何RESTful API,并仔细研究其文档。
通用对接技能已获得! 现在我们已经掌握了基本连接的设置,是时候讨论更复杂的协议了——CORS、身份验证和安全性。
📌 检查点:
- 确保你的FastAPI服务器正在运行。
- 确保你已将
API_BASE_URL
和app.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
前缀。