如何在多次处理POST数据时复制wsgi.input?

9 投票
3 回答
11401 浏览
提问于 2025-04-15 16:18

在WSGI中,POST数据是通过读取一个像文件一样的对象environ['wsgi.input']来获取的。如果在处理过程中,第二个元素也想读取POST数据,就可能会导致程序卡住,因为它会在没有更多数据可读的时候继续尝试读取。

那么,我该如何复制POST数据,以便可以多次处理呢?

3 个回答

1

如果你想一次性读取所有内容,可以先把内容读进来,然后创建一个像文件一样的CStringIO对象,把读取的内容放进去,最后再把它赋值回去,像这样:

import cStringIO
import copy
lines = []
for line in environ['wsgi.input']:
    lines.append(line)
newlines = copy.copy(lines)
environ['wsgi.input'] = cStringIO.StringIO(''.join(newlines))

当然,可能还有更有效的方法来做到这一点,但我发现wsgi的post处理在做一些复杂的事情时(比如多次读取post数据)比较脆弱。

12

你可以试着在环境中放回一个像文件一样的流的副本:

from cStringIO import StringIO

length = int(environ.get('CONTENT_LENGTH', '0'))
body = StringIO(environ['wsgi.input'].read(length))
environ['wsgi.input'] = body

不过,必须这么做有点不太好。理想情况下,应该只有一段代码来解析查询字符串和提交的内容,然后把结果交给其他部分使用。

8

去看看WebOb这个包。它提供了一些功能,可以让你把wsgi.input设置成可回溯的。这意味着你可以把输入流倒回去,这样就能通过不同的处理程序重新播放内容。即使你不使用WebOb,它的实现方式也很值得学习,因为我相信Ian会以合适的方式来做这件事。如果你想在文档中搜索相关结果,可以点击这里

撰写回答