Skip to content

19. FastAPI 响应类型_其他格式 ​

根据客户端需求选择响应格式 ​

API 常用 JSON,但页面、纯文本、跳转、无正文和持续输出都有各自合适的响应类型。声明 response_class 有助于文档描述;直接返回响应对象可以控制具体的头和状态码。

python
import asyncio
from fastapi import FastAPI, Response
from fastapi.responses import (
    HTMLResponse, PlainTextResponse, RedirectResponse, StreamingResponse,
)

app = FastAPI()

@app.get("/hello", response_class=PlainTextResponse)
def hello():
    return "你好,纯文本"

@app.get("/page", response_class=HTMLResponse)
def page():
    return "<h1>FastAPI 学习页</h1><p>这是 HTML。</p>"

@app.post("/submitted")
def submitted():
    return RedirectResponse(url="/page", status_code=303)

@app.delete("/cache", status_code=204)
def clear_cache():
    return Response(status_code=204)

@app.get("/stream")
async def stream():
    async def generate():
        for i in range(3):
            yield f"第 {i + 1} 段\n"
            await asyncio.sleep(0.2)
    return StreamingResponse(generate(), media_type="text/plain; charset=utf-8")

保存为 main.py,启动 uv run uvicorn main:app --reload。浏览器打开 /page 能看到页面;执行 curl.exe -N http://127.0.0.1:8000/stream 观察分段输出。-N 减少客户端输出缓冲,但代理和网络仍可能合并数据块。

重定向状态码影响后续方法 ​

303 通常让客户端在提交后转为 GET,适合“提交后跳转”。307、308 保留原请求方法,不应在没有 POST 路由的目标上盲目使用。若跳转地址来自用户输入,应限制允许的目标,避免任意外站跳转。

HTML、Cookie 和响应头 ​

直接拼接不可信输入到 HTML 会产生注入风险,渲染动态内容应使用自动转义模板。Cookie 可通过响应的 set_cookie 设置,按用途配置 httponly、secure、samesite 与有效期。

若用于登录会话,Cookie、CSRF、CORS 需要配合考虑;设置 Cookie 不等于完成认证。添加自定义头时,浏览器跨域脚本要读取该头还需在 CORS 中声明 expose_headers。

流式响应的限制 ​

一旦响应头和部分正文已发出,后续异常通常不能再改成普通 JSON 的 500。需要在流协议中定义错误事件、关闭行为和客户端重试策略。大模型输出将在第 38 篇用独立 SSE 示例演示。

练习:给纯文本响应增加一个自定义头;对比 303 和 307 的请求方法变化;确认 204 响应没有 JSON 正文。