WeHelp
FastAPI 是簡單易學、現代化、高效能的後端系統開發框架,近代 Python 最受歡迎的技術堆疊之一。
  1. 簡介、安裝、快速開始
  2. 主機名稱、埠號
  3. 路徑、路由處理
  4. 路徑參數處理
  5. 查詢參數處理
  6. 靜態檔案處理
  7. 回應格式處理
  8. 網址導向
  9. 網頁表單互動
  10. 網頁表單 POST 方法
  11. 樣板引擎
  12. 請求文本處理
  13. 常見的連線方法
  14. 參數資料驗證
  15. 使用者狀態管理
  16. 資料庫連線
回應格式處理
FastAPI 可以透過不同的 Response 類別,回應 JSON、純文字、HTML 或檔案內容給前端。 ## 1. JSON 格式 JSON 是最常見的 API 回應格式,前端通常使用 `fetch()` 或 Axios 接收。 ### 直接回傳 `dict` 或 `list` FastAPI 會自動將 Python 的 `dict`、`list` 等資料轉成 JSON。 ```python from fastapi import FastAPI app = FastAPI() @app.get("/user") def get_user(): return { "id": 1, "name": "Alice", "email": "alice@example.com" } ``` 回應內容: ```json { "id": 1, "name": "Alice", "email": "alice@example.com" } ``` ### 使用 `JSONResponse` 如果需要指定狀態碼、標頭或自訂回應,可以使用 `JSONResponse`。 ```python from fastapi import FastAPI from fastapi.responses import JSONResponse app = FastAPI() @app.get("/success") def success(): return JSONResponse( content={ "message": "操作成功", "data": [1, 2, 3] }, status_code=200 ) ``` 也可以回傳錯誤狀態: ```python @app.get("/error") def error(): return JSONResponse( content={"message": "找不到資料"}, status_code=404 ) ``` 前端使用 `fetch()`: ```javascript fetch("/user") .then(response => response.json()) .then(data => { console.log(data.name); }); ``` --- ## 2. 純文字格式 使用 `PlainTextResponse` 回傳 `text/plain`。 ```python from fastapi.responses import PlainTextResponse @app.get("/hello-text", response_class=PlainTextResponse) def hello_text(): return "Hello, FastAPI!" ``` 回應標頭通常會是: ```http Content-Type: text/plain; charset=utf-8 ``` 也可以直接建立 Response: ```python @app.get("/message") def message(): return PlainTextResponse( content="這是一段純文字", status_code=200 ) ``` 前端接收純文字: ```javascript fetch("/hello-text") .then(response => response.text()) .then(text => { console.log(text); }); ``` --- ## 3. HTML 格式 使用 `HTMLResponse` 回傳 HTML 內容。 ```python from fastapi.responses import HTMLResponse @app.get("/page", response_class=HTMLResponse) def page(): return """ <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>FastAPI Page</title> </head> <body> <h1>Hello FastAPI</h1> <p>這是 HTML 回應。</p> </body> </html> """ ``` 回應標頭: ```http Content-Type: text/html; charset=utf-8 ``` 瀏覽器直接開啟: ```text http://localhost:8000/page ``` 就會將內容解析成網頁。 也可以手動建立: ```python @app.get("/html") def html(): return HTMLResponse( content="<h1>歡迎使用 FastAPI</h1>", status_code=200 ) ``` --- ## 4. 回傳檔案內容 FastAPI 常見的檔案回應方式有兩種: - `FileResponse`:直接回傳伺服器上的檔案 - `StreamingResponse`:串流回傳檔案或動態產生的內容 --- ### 4.1 使用 `FileResponse` 假設專案中有: ```text project/ ├── main.py └── files/ └── example.pdf ``` 程式碼: ```python from fastapi import FastAPI from fastapi.responses import FileResponse app = FastAPI() @app.get("/download") def download_file(): return FileResponse( path="files/example.pdf", filename="example.pdf", media_type="application/pdf" ) ``` 瀏覽器通常會依照 `Content-Disposition` 決定下載或開啟檔案。 常見 `media_type`: ```text application/pdf image/png image/jpeg text/csv application/zip application/octet-stream ``` 如果希望強制下載,可以指定 `Content-Disposition`: ```python from fastapi.responses import FileResponse @app.get("/download-pdf") def download_pdf(): return FileResponse( path="files/example.pdf", filename="report.pdf", media_type="application/pdf", content_disposition_type="attachment" ) ``` 如果希望瀏覽器嘗試直接開啟,例如 PDF 或圖片,可以使用: ```python @app.get("/view-pdf") def view_pdf(): return FileResponse( path="files/example.pdf", filename="example.pdf", media_type="application/pdf", content_disposition_type="inline" ) ``` --- ### 4.2 回傳圖片 ```python @app.get("/image") def get_image(): return FileResponse( path="files/photo.png", media_type="image/png" ) ``` 前端可以直接設定圖片網址: ```html <img src="/image" alt="圖片"> ``` 或使用 JavaScript: ```javascript const image = document.querySelector("img"); image.src = "/image"; ``` --- ### 4.3 使用 `StreamingResponse` 當檔案很大,或內容是動態產生時,可以使用串流方式。 ```python from fastapi.responses import StreamingResponse def file_iterator(path: str): with open(path, "rb") as file: while chunk := file.read(1024 * 1024): yield chunk @app.get("/stream-file") def stream_file(): return StreamingResponse( file_iterator("files/large.zip"), media_type="application/zip", headers={ "Content-Disposition": 'attachment; filename="large.zip"' } ) ``` 這種方式不需要一次將整個檔案載入記憶體。 --- ## 5. 自訂 HTTP 標頭與狀態碼 所有 Response 都可以自訂狀態碼與 HTTP 標頭。 ```python from fastapi.responses import JSONResponse @app.get("/custom-response") def custom_response(): return JSONResponse( content={"message": "成功"}, status_code=201, headers={ "X-App-Version": "1.0", "Cache-Control": "no-cache" } ) ``` --- ## 6. 使用 `response_model` 定義 JSON 格式 如果希望限制或驗證 JSON 回應格式,可以搭配 Pydantic Model。 ```python from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class User(BaseModel): id: int name: str @app.get("/user-model", response_model=User) def get_user_model(): return { "id": 1, "name": "Alice", "extra_field": "會被過濾" } ``` 回應會符合 `User` 定義: ```json { "id": 1, "name": "Alice" } ``` --- ## 7. 常用 Response 類別整理 | Response 類別 | Content-Type | 用途 | |---|---|---| | 直接回傳 `dict`、`list` | `application/json` | JSON API | | `JSONResponse` | `application/json` | 自訂 JSON、狀態碼、標頭 | | `PlainTextResponse` | `text/plain` | 純文字 | | `HTMLResponse` | `text/html` | HTML 網頁 | | `FileResponse` | 依檔案類型 | 回傳伺服器上的檔案 | | `StreamingResponse` | 自訂 | 大檔案或串流內容 | 一個完整範例: ```python from fastapi import FastAPI from fastapi.responses import ( JSONResponse, PlainTextResponse, HTMLResponse, FileResponse ) app = FastAPI() @app.get("/json") def json_response(): return {"message": "JSON response"} @app.get("/text", response_class=PlainTextResponse) def text_response(): return "Plain text response" @app.get("/html", response_class=HTMLResponse) def html_response(): return "<h1>HTML response</h1>" @app.get("/file") def file_response(): return FileResponse( "files/example.pdf", filename="example.pdf", media_type="application/pdf" ) ``` 重點是:FastAPI 會根據不同的 Response 類別設定適當的 `Content-Type`,前端則依照資料格式使用 `response.json()`、`response.text()`,或直接將 URL 當作檔案、圖片或網頁來源使用。
相關學習地圖、教學課程
Python 後端工程、資料庫
從 0 開始,成為後端工程師的學習路徑。