FastAPI+前端交互:JavaScript调用FastAPI接口实战

一、前后端交互的基本原理

在Web开发中,前后端交互的核心是前端通过HTTP请求调用后端API,后端处理请求后返回数据,前端再将数据渲染到页面。例如,用户在前端界面输入信息,点击按钮,前端JavaScript会发送HTTP请求给后端(FastAPI),后端根据请求参数处理后返回结果,前端再展示这些结果。

二、准备工作

要实现前后端交互,需安装必要的工具和库:
1. 后端(FastAPI)
安装FastAPI和ASGI服务器uvicorn(用于运行FastAPI应用):

   pip install fastapi uvicorn

若需处理跨域请求,需安装CORSMiddleware(FastAPI内置,无需额外安装)。

  1. 前端(HTML+JavaScript)
    只需一个HTML文件(无需额外依赖,浏览器原生支持JavaScript)。

三、后端接口实战(FastAPI)

首先搭建一个简单的后端接口,实现数据的返回。

步骤1:创建后端文件main.py
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware  # 处理跨域

app = FastAPI()  # 初始化FastAPI应用

# 配置跨域:允许前端(开发阶段用"*",生产环境需指定具体域名)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 允许所有前端来源
    allow_credentials=True,
    allow_methods=["*"],  # 允许所有HTTP方法(GET/POST等)
    allow_headers=["*"]   # 允许所有请求头
)

# 1. 简单GET接口:返回JSON数据
@app.get("/api/hello")
async def get_hello():
    return {"message": "Hello, FastAPI!"}  # FastAPI自动将字典转为JSON

# 2. 带参数的GET接口:根据ID返回商品信息
@app.get("/api/items/{item_id}")
async def get_item(item_id: int):
    return {
        "item_id": item_id,
        "name": "Python教程",
        "price": 99.99,
        "desc": "适合初学者的FastAPI实战课程"
    }

# 3. POST接口:接收前端数据并返回处理结果
@app.post("/api/submit")
async def submit_data(data: dict):  # FastAPI自动解析JSON为Python字典
    return {
        "status": "success",
        "received": data,
        "message": "数据已接收并处理"
    }
步骤2:启动后端服务

在终端运行以下命令启动FastAPI应用(使用uvicorn服务器):

uvicorn main:app --reload  # main是文件名,app是FastAPI实例名,--reload自动热重载

启动成功后,访问 http://localhost:8000/api/hello 可看到返回的JSON数据,说明接口正常工作。

四、解决跨域问题

由于前端和后端默认运行在不同端口(如前端5500、后端8000),浏览器会拦截跨域请求。因此需在FastAPI中配置CORSMiddleware(步骤3已完成),允许前端跨域访问。

五、前端JavaScript调用接口(HTML+Fetch)

前端通过fetch API(浏览器原生支持)发起HTTP请求,调用后端接口并处理返回数据。

步骤1:创建前端HTML文件index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>FastAPI前端交互</title>
</head>
<body>
    <h1>FastAPI+JavaScript交互示例</h1>
    <button onclick="fetchGetHello()">调用GET /api/hello</button>
    <button onclick="fetchGetItem()">调用GET /api/items/123</button>
    <button onclick="fetchPostData()">调用POST /api/submit</button>
    <div id="result"></div>

    <script>
        // 1. 调用GET接口:获取简单信息
        async function fetchGetHello() {
            try {
                const response = await fetch("http://localhost:8000/api/hello");
                if (!response.ok) throw new Error(`状态码:${response.status}`);
                const data = await response.json();  // 解析JSON响应
                document.getElementById("result").innerHTML = `
                    <p>调用结果:${data.message}</p>
                `;
            } catch (error) {
                document.getElementById("result").innerHTML = `<p>错误:${error.message}</p>`;
            }
        }

        // 2. 调用GET接口:带参数
        async function fetchGetItem() {
            try {
                const itemId = 123;  // 可替换为用户输入的参数
                const response = await fetch(`http://localhost:8000/api/items/${itemId}`);
                if (!response.ok) throw new Error(`状态码:${response.status}`);
                const data = await response.json();
                document.getElementById("result").innerHTML += `
                    <p>商品信息:</p>
                    <p>ID:${data.item_id}</p>
                    <p>名称:${data.name}</p>
                    <p>价格:${data.price}</p>
                `;
            } catch (error) {
                document.getElementById("result").innerHTML += `<p>错误:${error.message}</p>`;
            }
        }

        // 3. 调用POST接口:发送数据给后端
        async function fetchPostData() {
            try {
                const userData = {
                    name: "小明",
                    age: 20,
                    email: "xiaoming@example.com"
                };
                const response = await fetch("http://localhost:8000/api/submit", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json"  // 必须指定为JSON格式
                    },
                    body: JSON.stringify(userData)  // 将对象转为JSON字符串
                });
                if (!response.ok) throw new Error(`状态码:${response.status}`);
                const result = await response.json();
                document.getElementById("result").innerHTML += `
                    <p>POST结果:</p>
                    <p>状态:${result.status}</p>
                    <p>接收的数据:${JSON.stringify(result.received)}</p>
                `;
            } catch (error) {
                document.getElementById("result").innerHTML += `<p>错误:${error.message}</p>`;
            }
        }
    </script>
</body>
</html>

六、运行与测试

  1. 确保后端已启动:uvicorn main:app --reload
  2. 打开前端index.html文件(直接用浏览器打开,无需额外服务器)
  3. 点击页面按钮,依次测试三个接口:
    - 调用GET /api/hello:显示后端返回的Hello, FastAPI!
    - 调用GET /api/items/123:显示商品信息
    - 调用POST /api/submit:后端返回接收的数据和状态

七、关键知识点总结

  1. 跨域问题:必须配置CORSMiddleware,允许前端跨域请求(生产环境需限制allow_origins为具体域名)。
  2. HTTP请求方法
    - GET:获取数据(无请求体,参数在URL中)
    - POST:提交数据(参数在请求体中,需设置Content-Type: application/json
  3. JSON数据:前后端通过JSON格式交换数据,fetch自动解析response.json()
  4. 错误处理:需检查HTTP状态码(response.ok)和网络异常,避免程序崩溃。

八、进阶扩展

  • Axios库:比fetch更简洁,支持拦截器、取消请求等功能(需额外安装:npm install axios)。
  • 前端框架:用React/Vue等框架构建复杂界面,配合axiosfetch调用接口。
  • 数据验证:后端可通过Pydantic模型验证前端提交的数据,提升安全性。

通过以上步骤,你已掌握FastAPI后端接口开发和前端JavaScript调用的核心技能,可进一步探索更复杂的业务场景!

小夜