首页
/ FastAPI 响应头设置完全指南:临时 Response 参数、直接返回与 CORS 暴露

FastAPI 响应头设置完全指南:临时 Response 参数、直接返回与 CORS 暴露

2026-09-06 14:51:03作者:邵娇湘

本篇指南基于 FastAPI 官方文档《Response Headers》展开,讲解在 FastAPI 中设置响应头(Response Headers)的两种核心方式:通过声明 Response 参数操作临时响应对象,以及直接返回带 headers 的 Response 实例。读完本文,你将掌握这两种方式的适用场景、与 response_model 的协同关系,以及浏览器端读取自定义头所需的 CORS 配置。

两种设置响应头的方式概览

FastAPI 允许你在以下两个位置控制响应头:

方式 适用场景 示例代码位置
声明 Response 参数(临时响应) 仍需要返回 dict、数据库模型等普通对象,或已声明 response_model 做过滤/转换时 docs_src/response_headers/tutorial002_py310.py
直接返回 Response 需要完全控制响应体与头,例如返回 JSON 字符串、自定义 Content-Language docs_src/response_headers/tutorial001_py310.py

两种方式可以同时出现在一个应用中,互不冲突。

方式一:使用 Response 参数(临时响应对象)

你可以在路径操作函数中声明一个类型为 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"}

(示例源码:docs_src/response_headers/tutorial002_py310.py

设置完头之后,你只需按平时的方式返回任何你需要的对象即可——dict、数据库模型等都可以。

关键点:即使你声明了 response_model,它仍然会照常用于过滤和转换你返回的对象。临时响应对象只贡献“头信息”(响应头、Cookie、状态码),响应体完全由你的返回值和 response_model 决定。

FastAPI 会从该临时响应中提取头(也包括 Cookie 和状态码),并将它们合并进最终包含你返回值(经 response_model 过滤后)的响应中。

这个机制在源码中有明确的体现:

  • fastapi/dependencies/utils.pysolve_dependencies() 中,当调用方没有传入 response 时,会创建一个临时 Response(),并主动删除其中的 content-length 头、把 status_code 置为 None,表明这个对象只用于承载头信息:
if response is None:
    response = Response()
    del response.headers["content-length"]
    response.status_code = None
  • fastapi/routing.py 的路由处理函数中,路径操作函数返回普通对象时,FastAPI 先经过 serialize_response()(受 response_model 约束)生成响应,随后执行:
response.headers.raw.extend(solved_result.response.headers.raw)

这一行(约 L750)正是“从临时响应提取头、合并进最终响应”的实现:solved_result.response 就是传给路径操作函数的临时 Response

在依赖中同样可用:你也可以在依赖函数中声明 Response 参数并设置头(和 Cookie),例如:

def my_dependency(response: Response):
    response.headers["X-From-Dependency"] = "true"

依赖中设置的头会经过同一套依赖解析流程(solve_dependencies),最终一并合并到响应上。因此可以在全局/局部依赖中统一添加追踪 ID、版本号等公共响应头。

方式二:直接返回 Response

如果你要直接返回一个 Response 对象(参见文档 Return a Response Directly),也可以在构造时把 headers 作为额外参数传入:

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)

(示例源码:docs_src/response_headers/tutorial001_py310.py

此时 JSONResponseheaders 参数会原样生效。从源码可以看到,当路径操作函数的返回值 isinstance(raw_response, Response) 时(fastapi/routing.py 约 L711),FastAPI 会直接把它作为最终响应返回(仅在其没有 background 任务时补上 solved_result.background_tasks),不再走 response_model 过滤逻辑——这是与方式一的本质区别。

技术细节:fastapi.responsesstarlette.responses

你也可以使用 from starlette.responses import Responsefrom starlette.responses import JSONResponse

FastAPI 提供的 fastapi.responsesstarlette.responses 中的类型基本是同一套,只是作为开发便利的再导出(re-export)。可以从 fastapi/responses.py 直接看到:

from starlette.responses import JSONResponse as JSONResponse  # noqa
from starlette.responses import Response as Response  # noqa
...

其中绝大多数响应类型(FileResponseHTMLResponsePlainTextResponseRedirectResponseStreamingResponse 等)直接来自 Starlette。而 Response 因为经常被用于设置响应头和 Cookie,FastAPI 还在 fastapi.Response 顶层也提供了它,方便直接 from fastapi import Response 导入。

自定义头与 CORS 暴露

使用自定义头时注意以下两点:

  1. 私有/自定义专有头可以使用 X- 前缀命名(如示例中的 X-Cat-Dog),避免与标准 HTTP 头冲突;
  2. 让浏览器端 JavaScript 能读到自定义头:浏览器出于安全策略,默认只暴露 Content-TypeSet-Cookie 等少数响应头给跨域请求的 JS 代码。如果你的自定义头需要被浏览器中的客户端看到,必须在 CORS 配置中加入它们——在 CORS (跨域资源共享) 的配置中使用 Starlette CORS 中间件文档中的 expose_headers 参数:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    expose_headers=["X-Cat-Dog"],
)

行为验证:官方测试用例

上述两种用法在仓库测试中都有对应的断言,可以直接查看验证逻辑:

小结

  • 需要保留 response_model 过滤、只额外加头/Cookie/状态码 → 声明 Response 参数,在依赖或路径操作函数中写入 response.headers
  • 需要完全自定义响应体 → 直接返回 Response/JSONResponse 并在构造参数中传 headers
  • 浏览器端要读自定义头 → 用 CORS 中间件的 expose_headers 显式暴露;
  • 底层原理见 fastapi/dependencies/utils.py(临时 Response() 的创建)与 fastapi/routing.pyresponse.headers.raw.extend(...) 的头部合并)。
登录后查看全文
热门项目推荐
相关项目推荐