【问题标题】:Why does WSGI have to use start_response and return an iterator?为什么 WSGI 必须使用 start_response 并返回一个迭代器?
【发布时间】:2014-08-31 06:05:34
【问题描述】:

非WSGI方式:

def my_view(request):
    request.start_response('200 OK')
    request.send_header('Content-Type', 'text/plain')
    request.end_headers()
    request.write('Hello World!')
    request.write('Goodbye World!')
    request.end()

WSGI 方式:

def my_view(environ, start_response):
    def generate():
        yield 'Hello World!'
        yield 'Goodbye World!'
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return generate()

代码来自this blog,虽然我不太明白..

从上面可以看出,非 WSGI 看起来要容易得多。 WSGI 看起来很混乱。为什么start_reponse 必须在my_view 中传递?为什么my_view 必须返回一个迭代器? WSGI 方式中的request 对象在哪里?

有人对此有想法吗?

【问题讨论】:

标签: python django web cgi wsgi


【解决方案1】:

简单的答案是:它必须是这种方式,因为 WSGI 以这种方式指定它。 ;-)

start_response() 在两个示例中都被传递,在第一个示例中,它只是与 request 对象“捆绑”在一起,WSGI 将环境变量与可调用对象分开以启动响应。

返回一个可迭代对象可以更轻松地以惰性方式生成响应并链接多个中间件,而无需一次将整个内容从一个中间件移交给另一个中间件。顺便说一句,生成器函数并不是最简单的解决方案,因为返回值必须是可迭代的,而不是迭代器本身,甚至不是生成器。所以这将是 WSGI 应用程序的最小示例:

def app(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')])
    return ['Hello world!\n']

我认为这看起来实际上比非 WSGI 示例更简单、更容易。

【讨论】:

  • 您能否将其编辑为 Python3 的 [b'Hello world!\n'],它区分字符串和字节串?它也适用于 Python2。否则,这将在 Python3 上出现可怕的“来自迭代器的未处理对象”错误,并且页面上不会显示任何内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 2020-03-19
  • 2019-12-28
相关资源
最近更新 更多