如何读取由WSGI的 start_response设置的响应头

后端开发 2026-07-08

在找一种方法来读取WSGI start_response 对象设置了哪些头信息。我们知道头信息被存储在某处,因为它们在返回语句之后才会被传输,但它们存储在哪里,以及如何访问它们?

示例代码:

from wsgiref.simple_server import make_server
from wsgiref.headers import Headers

def hello_world_app(environ, start_response):
    status = "200 OK"  # HTTP Status
    headers = [("Content-type", "text/plain; charset=utf-8")]  # HTTP Headers
    start_response(status, headers)
    print("???") # <- read response header here that has been set by start_response
    return [b"Hello workld"]
environ.items()]

with make_server("", 8000, hello_world_app) as httpd:
    print("Serving on port 8000...")
    httpd.serve_forever()

解决方案

你的应用程序函数 hello_world_app 正在被 BaseHandler 调用,具体在此处 在此处:

            self.result = application(self.environ, self.start_response)

头信息也被存储在那里,正如你在基类处理程序的此处看到的:在此处:

        self.headers = self.headers_class(headers)

于是问题就变成:如何在应用程序函数内部访问基类处理程序的实例?self.environ 只是一个普通字典,因此不可访问,但 self.start_response 是一个绑定方法——例如 如何在Python中找到绑定方法的实例? 你可以通过 __self__ 访问它绑定的实例,示例如下:

print(start_response.__self__.headers)

其输出为:

Content-type: text/plain; charset=utf-8

这归因于 Headers.__str__ 的实现。


如果你想用 Python类型注解 来做这件事,请注意:

因此最好只是禁用对该行的静态检查:

from collections.abc import Iterable
from typing import Any
from wsgiref.simple_server import make_server
from wsgiref.types import StartResponse


def hello_world_app(
    environ: dict[str, Any], start_response: StartResponse
) -> Iterable[bytes]:
    start_response("200 OK", [("Content-type", "text/plain; charset=utf-8")])
    print(start_response.__self__.headers)  # type: ignore
    return [b"Hello world"]


with make_server("", 8000, hello_world_app) as httpd:
    print("Serving on port 8000...")
    httpd.serve_forever()

这将让例如 mypy 等工具满意。


1 这一定义也正确——起始响应可调用对象 是Web服务器网关接口的一个通用部分,不要求必然是绑定方法,通常也不能依赖于它就是一个绑定方法。只有在使用此参考实现的具体情形下,我们知道它在运行时会是一个绑定方法,除非未来实现有变。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章