无论Content-Type标题如何,都可以在Python Flask中获取原始的POST正文

以前,我问过如何在Flask请求中接收数据,因为request.data是空的。 答案解释说, request.data是原始文章的主体,但是如果表单数据被parsing,它将是空的。 我怎样才能无条件地获得原始的职位?

 @app.route('/', methods=['POST']) def parse_request(): data = request.data # empty in some cases # always need raw data here, not parsed form data 

使用request.get_data()获取原始数据,而不pipe内容types。 数据被caching,随后您可以随意访问request.datarequest.jsonrequest.form

如果首先访问request.data ,它将首先调用带有参数的get_data来parsing表单数据。 如果请求具有表单内容types( multipart/form-dataapplication/x-www-form-urlencodedapplication/x-url-encoded ),则原始数据将被消耗。 在这种情况下, request.datarequest.json将显示为空。

当mimetypes不被识别时,有request.stream

 data = request.stream.read() 

我刚刚遇到了这个问题,我想你们中的一些人可能会从我的解决scheme中受益。 我创build了一个WSGI中间件类,用于从套接字保存原始POST主体。 我将这个值保存在WSGIvariables'environ'中,所以我可以在我的Flask应用程序中将其引用为request.environ ['body_copy']。

您需要小心,发布数据不是太大,或者您的服务器上可能有内存问题。

 class WSGICopyBody(object): def __init__(self, application): self.application = application def __call__(self, environ, start_response): from cStringIO import StringIO length = environ.get('CONTENT_LENGTH', '0') length = 0 if length == '' else int(length) body = environ['wsgi.input'].read(length) environ['body_copy'] = body environ['wsgi.input'] = StringIO(body) # Call the wrapped application app_iter = self.application(environ, self._sr_callback(start_response)) # Return modified response return app_iter def _sr_callback(self, start_response): def callback(status, headers, exc_info=None): # Call upstream start_response start_response(status, headers, exc_info) return callback app.wsgi_app = WSGICopyBody(app.wsgi_app) request.environ['body_copy'] # This is the raw post body you can use in your flask app 

我终于明白,如​​果我这样做:

 request.environ['CONTENT_TYPE'] = 'application/something_Flask_ignores' 

那么request.data实际上会有post数据。 这是如果你不能控制客户端的请求,只想在服务器上覆盖它。