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 正文。