【FastAPI】 响应类型详解:从默认 JSON 到自定义响应

FastAPI 响应类型详解:从默认 JSON 到自定义响应(HTML/文件/流/重定向)

一、FastAPI 响应机制概述

FastAPI 默认会将路径操作函数返回的 Python 对象(如 dictlistPydantic Model)自动转换为 JSON 格式 ,并通过 JSONResponse 返回客户端。

转换依赖 jsonable_encoder,无需手动序列化。

python 复制代码
return {"message": "Hello World"}  # 自动转为 JSON

但若需返回非 JSON 数据(如 HTML、文件、流、纯文本等),必须显式指定响应类型。


二、响应类型设置方式(共 6 种)

方式一:在 @app.get() 装饰器中设置 response_class

适用场景 :固定返回类型,如 HTML纯文本文件(非动态流式)

python 复制代码
from fastapi import FastAPI
from fastapi.responses import HTMLResponse, PlainTextResponse, FileResponse

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
async def root():
    return "<h1>这是一级标题</h1>"
响应类型 response_class 用途
HTMLResponse HTMLResponse 返回 HTML 内容(如网页)
PlainTextResponse PlainTextResponse 返回纯文本(不含 HTML 标签)
FileResponse FileResponse 返回文件下载(如图片、txt、pdf)
示例:纯文本响应
python 复制代码
@app.get("/text", response_class=PlainTextResponse)
async def get_text():
    return "这是纯文本"
示例:文件下载
python 复制代码
@app.get("/file/txt", response_class=FileResponse)
async def get_file():
    return "./files/1.txt"

💡 注意:FileResponse 会自动设置 Content-Disposition: attachment,触发下载。


方式二:直接返回响应对象(推荐用于动态响应)

适用场景:文件流、图片、自定义 MIME 类型、重定向、流式响应

返回图片(FileResponse
python 复制代码
@app.get("/file/picture")
async def get_picture():
    return FileResponse("./files/1.png")

自动设置 Content-Type: image/png

流式响应(StreamingResponse
python 复制代码
from fastapi.responses import StreamingResponse
@app.get("/stream")
async def get_stream():
    def iter_file():
        with open("./files/1.png", "rb") as f:
            while chunk := f.read(1024):
                yield chunk

    return StreamingResponse(iter_file(), media_type="image/png")

使用生成器函数模拟流式传输,适用于大文件、视频流等。

自定义 MIME 类型与文件名
python 复制代码
@app.get("/file/download")
async def download_file():
    return FileResponse(
        path="./files/1.txt",
        media_type="text/plain",   # 自定义 MIME 类型
        filename="news.txt"        # 下载时的文件名
    )

可通过 filename 设置下载后文件名,打破原文件名限制。


方式三:使用 RedirectResponse(重定向)

python 复制代码
from fastapi.responses import RedirectResponse

@app.get("/redirect")
async def redirect_to_home():
    return RedirectResponse(url="/")

浏览器将跳转到 / 地址,返回 302 状态码。

重定向到外链(如百度)
python 复制代码
@app.get("/to-baidu")
async def to_baidu():
    return RedirectResponse(url="https://www.baidu.com")

方式四:自定义响应数据格式(response_model + Pydantic)

Pydantic 模型定义 API 返回结构,实现类型安全与文档自动生成。

步骤 1:定义 Pydantic 模型
python 复制代码
from pydantic import BaseModel

class News(BaseModel):
    id: int
    title: str
    content: str
步骤 2:在路由中启用 response_model
python 复制代码
@app.get("/news/{id}", response_model=News)
async def get_news(id: int):
    return {
        "id": id,
        "title": "这是新闻标题",
        "content": "这是新闻内容"
    }

如果返回数据不符合 News 模型结构 → FastAPI 会返回 422 错误

Swagger UI 会根据 response_model 生成响应示例


三、FastAPI 响应类型总结表

响应类型 用途 何时使用 示例
JSONResponse(默认) 返回 JSON 数据 一般 API 接口 return {"msg": "ok"}
HTMLResponse 返回 HTML 内容 页面渲染、内嵌 HTML response_class=HTMLResponse
PlainTextResponse 返回纯文本 日志、简单信息 response_class=PlainTextResponse
FileResponse 文件下载 下载 PDF、TXT、图片 return FileResponse("./file.txt")
StreamingResponse 流式响应 大文件、视频、音频流 StreamingResponse(generator, media_type="video/mp4")
RedirectResponse 重定向 跳转页面、登录后跳转 return RedirectResponse(url="/")

四、易错点 & 注意事项

易错点 说明 解决方案
response_class 放在函数外 导致 AttributeError 必须在装饰器里写 response_class=...
FileResponse 路径写错 文件找不到,返回 404 使用 os.pathPath 拼接路径
❌ 流式响应未使用生成器 报错或无法传输 def iter_func(): yield chunk
response_model 返回字段类型不匹配 返回 422 错误 保证数据完全符合模型结构
❌ 忘记 import 响应类 编译错误 一定要导入:from fastapi.responses import ...

五、完整代码示例(可直接运行)

python 复制代码
from fastapi import FastAPI
from fastapi.responses import (
    HTMLResponse,
    PlainTextResponse,
    FileResponse,
    StreamingResponse,
    RedirectResponse
)
from pydantic import BaseModel
import os

app = FastAPI()

# 1. 默认 JSON 响应(自动)
@app.get("/")
async def root():
    return {"message": "Hello World"}

# 2. HTML 响应(固定类型)
@app.get("/html", response_class=HTMLResponse)
async def get_html():
    return "<h1>这是网页标题</h1>"

# 3. 纯文本响应
@app.get("/text", response_class=PlainTextResponse)
async def get_text():
    return "这是纯文本内容"

# 4. 文件下载(自动触发下载)
@app.get("/file/download")
async def get_txt():
    return FileResponse("./files/1.txt", filename="news.txt")

# 5. 图片响应
@app.get("/image")
async def get_image():
    return FileResponse("./files/1.png")

# 6. 流式响应(支持大文件)
@app.get("/stream")
async def stream_video():
    def iter_file():
        with open("./files/1.png", "rb") as f:
            while chunk := f.read(1024):
                yield chunk

    return StreamingResponse(iter_file(), media_type="image/png")

# 7. 重定向
@app.get("/redirect")
async def redirect_home():
    return RedirectResponse(url="/")

# 8. 自定义响应数据格式(Pydantic + response_model)
class News(BaseModel):
    id: int
    title: str
    content: str

@app.get("/news/{id}", response_model=News)
async def get_news(id: int):
    return {
        "id": id,
        "title": "FastAPI 响应类型详解",
        "content": "学习 FastAPI 的重要知识点"
    }
相关推荐
智算菩萨2 小时前
【Tkinter】15 样式与主题深度解析:ttk 主题系统、Style 对象与跨平台样式管理实战
开发语言·python·ui·ai编程·tkinter
weixin_419349792 小时前
Python 项目中生成 requirements.txt 文件
开发语言·python
第一程序员2 小时前
Python与区块链:非科班转码者的指南
python·github
liu****2 小时前
LangChain-AI应用开发框架(六)
人工智能·python·langchain·大模型应用·本地部署大模型
witAI3 小时前
**AI仿真人剧制作2025推荐,专业团队与创新技术引领未来**
人工智能·python
♪-Interpretation3 小时前
第五节:Python的流程控制语句
python
shark22222224 小时前
Python 爬虫实战案例 - 获取社交平台事件热度并进行影响分析
开发语言·爬虫·python
m0_564876844 小时前
提示词工程手册学习
人工智能·python·深度学习·学习
波诺波5 小时前
p1项目system_model.py代码
开发语言·python