无论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.data
, request.json
, request.form
。
如果首先访问request.data
,它将首先调用带有参数的get_data
来parsing表单数据。 如果请求具有表单内容types( multipart/form-data
, application/x-www-form-urlencoded
或application/x-url-encoded
),则原始数据将被消耗。 在这种情况下, request.data
和request.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数据。 这是如果你不能控制客户端的请求,只想在服务器上覆盖它。