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調用的核心技能,可進一步探索更復雜的業務場景!

小夜