在WSGI应用中应选用start_response()还是Header.add_header()?
解决WSGI中start_response的响应头记录与追加问题
问题1:获取已设置的响应头用于日志
你当前代码里新建的Headers()是空对象,和传给start_response的headers完全无关,自然拿不到已设置的头。解决思路是提前保存并包装响应头:
- 在调用
start_response前,先把定义好的headers列表留存,或者用wsgiref.headers.Headers直接包装这个列表,后续就能直接读取做日志。
修改后的示例代码:
from wsgiref.simple_server import make_server from wsgiref.headers import Headers def hello_world_app(environ, start_response): status = "200 OK" # 定义并保存初始响应头 headers = [("Content-type", "text/plain; charset=utf-8")] # 用Headers包装,方便后续读取和操作 response_headers = Headers(headers) start_response(status, headers) # 直接读取已设置的头用于日志 print(f"日志:Content-Type 响应头为 {response_headers.get('Content-type')}") return [("%s: %s\n" % (key, value)).encode("utf-8") for key, value in environ.items()]
问题2:追加额外响应头
有两种可靠实现方式:
- 提前追加固定头:如果额外头是预先确定的,直接加到初始headers列表里即可。
- 用start_response返回的write函数动态追加:如果是调用start_response后才需要添加的头,用start_response返回的write函数来添加(注意:必须在返回响应体之前调用,否则响应头已发送给客户端,无法修改)。
示例代码展示两种方式:
from wsgiref.simple_server import make_server from wsgiref.headers import Headers def hello_world_app(environ, start_response): status = "200 OK" headers = [("Content-type", "text/plain; charset=utf-8")] # 方式1:提前追加固定自定义头 headers.append(("X-Custom-Fixed", "pre-defined-value")) # 调用start_response,获取返回的write函数 write = start_response(status, headers) # 方式2:动态追加头(必须在返回响应体前执行) write(b"X-Custom-Dynamic: runtime-value\r\n") # 记录所有响应头(含追加的内容) response_headers = Headers(headers) response_headers.add_header("X-Custom-Dynamic", "runtime-value") print(f"完整响应头:{dict(response_headers)}") return [("%s: %s\n" % (key, value)).encode("utf-8") for key, value in environ.items()]
关键注意事项
- 一旦返回的响应体开始被服务器迭代(即return的可迭代对象开始输出),响应头就会被发送给客户端,此时再尝试添加头会无效,甚至触发错误。
wsgiref.headers.Headers是WSGI提供的工具类,可以将headers列表转换为更易操作的对象,支持get、add_header等便捷方法。
内容的提问来源于stack exchange,提问作者NickC
相关产品推荐
相关产品推荐

