【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 的重要知识点"
    }
相关推荐
IT策士13 小时前
Django 从 0 到 1 打造完整电商平台:为什么用 Django 做电商?
后端·python·django
zkkkkkkkkkkkkk13 小时前
Linux进行管理工具Supervisor配置与使用
linux·python·supervisor
2301_7838486514 小时前
mysql数据库迁移到云平台流程_使用数据传输服务DTS工具
jvm·数据库·python
开发者联盟league14 小时前
linux普通用户使用pip安装模块
linux·python·pip
老纪14 小时前
如何解决OUI图形界面无法调用_xhost与DISPLAY变量设置
jvm·数据库·python
知行合一。。。14 小时前
Python--05--面向对象(继承,多态)
android·开发语言·python
m0_6174939414 小时前
PyTorch CUDA设备不可用错误解决方案
人工智能·pytorch·python
小郑加油15 小时前
python学习Day15:综合训练——数据清洗与缺失值补充
开发语言·python·学习
完成大叔15 小时前
Agent入门:用本地模型从零搭建
开发语言·python·langchain
qxwlcsdn15 小时前
CSS如何实现元素镜像翻转_使用transformscalex负值
jvm·数据库·python