如何在Starlette应用中访问响应头?无需自定义中间件能否实现?
一、如何在Starlette应用中访问响应头?
1. 路由函数内直接操作
如果手动构建了Response(或JSONResponse这类子类),直接通过response.headers就能访问,它是个支持字典操作的MutableHeaders对象:
from starlette.responses import JSONResponse async def demo_route(request): response = JSONResponse({"status": "ok"}) # 读取已有的响应头 ct_header = response.headers.get("Content-Type") # 添加自定义响应头 response.headers["X-App-Version"] = "1.0.0" return response
如果是返回字符串、字典让Starlette自动生成响应的场景,先把返回值转成响应对象再操作:
async def auto_resp_route(request): resp_content = {"msg": "auto-generated"} response = JSONResponse(resp_content) # 打印所有响应头 print(dict(response.headers)) return response
2. 通过中间件全局拦截
如果需要在响应发送给客户端前统一处理或读取响应头,自定义中间件是标准方案:
from starlette.middleware.base import BaseHTTPMiddleware class HeaderInspectMiddleware(BaseHTTPMiddleware): async def dispatch(self, request, call_next): # 先执行路由逻辑拿到响应 response = await call_next(request) # 读取所有响应头 all_headers = dict(response.headers) # 比如获取Content-Length content_len = response.headers.get("Content-Length") print(f"响应内容长度: {content_len}") return response
然后把中间件注册到应用:
from starlette.applications import Starlette app = Starlette() app.add_middleware(HeaderInspectMiddleware)
二、无需自定义中间件,能获取中间件添加的响应头吗?
不行。
Starlette的中间件执行逻辑是:请求进来时按添加顺序依次执行,响应返回时则按相反顺序处理。以SessionMiddleware为例,它是在你的路由函数执行完成后,才会往响应里添加Set-Cookie头的。所以在路由函数内部,你拿到的响应对象还没经过SessionMiddleware的处理,根本看不到它设置的Cookie信息。
要获取这类由中间件添加的响应头,必须写自定义中间件,而且要注意添加顺序——你的自定义中间件要放在SessionMiddleware之后注册,这样响应返回时,你的中间件会在SessionMiddleware处理完响应后执行,才能拿到完整的响应头。
比如要提取SessionCookie的过期时间,可以这么做:
from starlette.middleware.base import BaseHTTPMiddleware from starlette.middleware.sessions import SessionMiddleware class SessionCookieParserMiddleware(BaseHTTPMiddleware): async def dispatch(self, request, call_next): response = await call_next(request) set_cookie = response.headers.get("Set-Cookie") if set_cookie: # 拆分Cookie的各个参数 cookie_params = set_cookie.split("; ") for param in cookie_params: if param.startswith("expires="): expires = param.split("=")[1] print(f"Session Cookie过期时间: {expires}") return response # 注册顺序很重要:先加SessionMiddleware,再加自定义中间件 app.add_middleware(SessionMiddleware, secret_key="your-secure-secret-key") app.add_middleware(SessionCookieParserMiddleware)
另外要注意,默认的SessionMiddleware不会设置“最后访问时间”这类自定义Cookie参数,如果需要这个信息,你得自己扩展SessionMiddleware,在更新会话时手动添加对应的参数到Set-Cookie头里。
内容的提问来源于stack exchange,提问作者ZSwat
相关产品推荐
相关产品推荐

