正如您已经指出的那样,您的中间件使后面的内容为
request.form空。这是因为
request.form正在从类似文件的对象中读取。引用PEP
333:
wsgi.input-
一个输入流(类似文件的对象),可以从中读取HTTP请求主体。(服务器或网关可以根据应用程序的请求按需执行读取,或者可以预先读取客户端的请求主体并将其缓存在内存中或磁盘上,或者使用任何其他技术来提供这种输入流,偏好)。
请注意,本段不会告诉我们这个“类似文件的对象”是否可以将指针重置为文件的开头。实际上,如果我们尝试以下应用程序:
from werkzeug.serving import run_simpledef app(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) yield str(dir(environ['wsgi.input']))run_simple('localhost', 5000, app)它没有显示该文件对象具有
seek方法的任何索引。
因此,您 可以做的
是将所有内容读取到一个名为的字节串中
data,并替换
wsgi.input为
BytesIO(data),确实有
seek一种可以使用的方法。
这样做会带来一些缺点 ,最明显的是,保证所有上传的数据在传递给应用程序之前都已被完全读取到内存中。也许还有一些我不了解的 危险情况
,这就是为什么我从不冒险尝试在实际应用程序中进行以下操作的原因:
from werkzeug.formparser import parse_form_datafrom werkzeug.wsgi import get_input_streamfrom io import BytesIOclass MethodMiddleware(object): """Don't actually do this. The disadvantages are not worth it.""" def __init__(self, app): self.app = app def __call__(self, environ, start_response): if environ['REQUEST_METHOD'].upper() == 'POST': environ['wsgi.input'] = stream = BytesIO(get_input_stream(environ).read()) formdata = parse_form_data(environ)[1] stream.seek(0) method = formdata.get('_method', '').upper() if method in ('GET', 'POST', 'PUT', 'DELETE'): environ['REQUEST_METHOD'] = method return self.app(environ, start_response)


