首页
/ FastAPI 响应头设置完全指南:Response 参数写入与直接返回 Response 两种方式

FastAPI 响应头设置完全指南:Response 参数写入与直接返回 Response 两种方式

2026-09-05 09:38:22作者:袁立春Spencer

本文基于 FastAPI 官方文档《Response Headers》(docs/de/docs/advanced/response-headers.md)展开,讲解在 FastAPI 中为 HTTP 响应添加自定义头的两条完整路径:一是在路径操作函数中声明 Response 参数写入头、同时照常返回任意 Python 对象;二是直接构造并返回 Response 实例(如 JSONResponse)时通过 headers 参数一次性传入。读完本文,你可以掌握"临时响应对象"的底层工作机制,理解为什么声明了 response_model 时头信息依然生效,以及如何配合 CORS 的 expose_headers 让浏览器客户端读到自定义头。

一、方式一:声明 Response 参数,边返回对象边设置响应头

最常见的场景是:你的路径操作函数需要继续返回 dict、数据库模型等普通对象,同时希望附加一些响应头。此时可以在函数签名中声明一个 Response 类型的参数(和声明 Cookie 参数的用法一致),然后在函数体内向这个"临时"响应对象写入头:

from fastapi import FastAPI, Response

app = FastAPI()


@app.get("/headers-and-object/")
def get_headers(response: Response):
    response.headers["X-Cat-Dog"] = "alone in the world"
    return {"message": "Hello World"}

以上示例来自官方教程源码 tutorial002_py310.py。关键点:

  • 返回值不受影响:设置完头之后,你可以像平时一样返回任意对象(dict、数据库模型、Pydantic 模型等),FastAPI 会负责序列化;
  • response_model 依然生效:如果你为该路径操作声明了 response_model,它仍然会用于过滤和转换你返回的对象,头信息不会被"吃掉";
  • 工作原理:FastAPI 会用这个临时响应对象来提取你设置的头(同时也包括 Cookie 和状态码),再把这些内容合并进最终返回给客户端的响应中——最终响应体是你返回值经 response_model 过滤后的结果。

"临时响应"这个说法并非比喻,源码可以直接佐证。在依赖求解入口 solve_dependencies 中,当调用链尚未提供响应对象时,FastAPI 会先创建一个空 Response 占位:

if response is None:
    response = Response()
    del response.headers["content-length"]
    response.status_code = None  # type: ignore

可以看到 FastAPI 专门删除了预置的 content-length 头、并把状态码置空——因为真正的长度和状态码要等最终响应体确定后才能计算。这个"空壳"会沿着依赖树传递(solve_dependencies 在递归处理子依赖时会把同一个 response 继续传下去,见 fastapi/dependencies/utils.py),路径操作函数和任何中间依赖都能往里写头,请求处理完毕后再统一落到最终响应上。

进阶用法:在依赖中声明 ResponseResponse 参数并不限于路径操作函数本身——你可以在任何**依赖(dependency)**中声明 Response 参数,并在依赖里设置头(以及 Cookie)。由于依赖先于路径操作函数执行,这在"全局统一附加某类头"的场景(如请求追踪 ID、版本标识头)中非常实用。

二、方式二:直接返回 Response,通过 headers 参数传入

另一种方式是直接返回一个响应对象,此时头通过构造响应的 headers 参数传入。以 JSONResponse 为例(完整代码见 tutorial001_py310.py):

from fastapi import FastAPI
from fastapi.responses import JSONResponse

app = FastAPI()


@app.get("/headers/")
def get_headers():
    content = {"message": "Hello World"}
    headers = {"X-Cat-Dog": "alone in the world", "Content-Language": "en-US"}
    return JSONResponse(content=content, headers=headers)

两种方式的取舍:

维度 Response 参数方式 直接返回 Response
响应体来源 返回普通对象,走 FastAPI 序列化 + response_model 过滤 由你显式构造(如 JSONResponse(content=...)
头的设置时机 函数体内逐条写入 response.headers 构造时通过 headers= 字典一次性传入
适用场景 常规 JSON 接口、需要在依赖中加头 需要完全掌控响应对象(自定义媒体类型、流式响应等)

两种方式可以混用:例如依赖里先用 Response 参数写入公共头,路径操作再返回一个自定义 Response 对象。

三、技术细节:fastapi.responsesfastapi.Response 从哪来

官方文档的"Technical Details"部分指出:你也可以写 from starlette.responses import Responsefrom starlette.responses import JSONResponse。FastAPI 只是把 Starlette 的响应类原样转手提供,作为开发便利性封装;绝大多数可用的响应类本体都来自 Starlette。源码印证如下,fastapi/responses.py 几乎全部是对 Starlette 的再导出:

from starlette.responses import FileResponse as FileResponse  # noqa
from starlette.responses import HTMLResponse as HTMLResponse  # noqa
from starlette.responses import JSONResponse as JSONResponse  # noqa
from starlette.responses import PlainTextResponse as PlainTextResponse  # noqa
from starlette.responses import RedirectResponse as RedirectResponse  # noqa
from starlette.responses import Response as Response  # noqa
from starlette.responses import StreamingResponse as StreamingResponse  # noqa

因为 Response 被高频用于设置头和 Cookie,FastAPI 进一步把它提升为顶级导出,所以 from fastapi import Response(如 tutorial002_py310.py 第 1 行)是合法写法。

值得注意的是 fastapi/responses.py 中另有两个已标记弃用的响应类 UJSONResponseORJSONResponse:当前版本 FastAPI 在设置了返回类型或 response_model 时会通过 Pydantic 直接把数据序列化为 JSON 字节,无需再依赖这两个自定义响应类。如果你在维护旧代码时见到它们,可以按弃用提示迁移到 response_model 方案。

四、自定义头:X- 前缀与 CORS expose_headers

官方文档特别强调两条约束,涉及跨域场景时务必注意:

  1. 私有自定义头建议使用 X- 前缀。这是 Web 生态的通用约定,用于把"非标准、自有用途"的头与 IETF 标准头区分开,例如示例中的 X-Cat-Dog
  2. 浏览器客户端要"看见"自定义头,必须在 CORS 配置中暴露它。浏览器出于安全策略,默认只向 JavaScript 暴露少数标准响应头;如果你的自定义头需要被浏览器端的 JS 读取,必须把它加入 CORS 中间件的 expose_headers 参数。FastAPI 中通过 app.add_middleware(CORSMiddleware, ..., expose_headers=[...]) 配置,参数语义遵循 Starlette 的 CORS 中间件规范。更多背景可参考仓库中的 CORS 教程章节 docs/de/docs/tutorial/cors.md

五、小结与延伸阅读

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384