之前,我问过How to get data received in Flask request,因为request.data
是空的。答案解释说request.data
是原始帖子正文,但如果解析表单数据则为空。如何无条件地获得原始邮政体?
@app.route('/', methods=['POST'])
def parse_request():
data = request.data # empty in some cases
# always need raw data here, not parsed form data
答案 0 :(得分:190)
使用request.get_data()
获取原始数据,无论内容类型如何。数据已缓存,您随后可以随意访问request.data
,request.json
,request.form
。
如果您首先访问request.data
,它将使用参数调用get_data
来首先解析表单数据。如果请求具有表单内容类型(multipart/form-data
,application/x-www-form-urlencoded
或application/x-url-encoded
),则将使用原始数据。在这种情况下,request.data
和request.json
将显示为空。
答案 1 :(得分:26)
当无法识别mime类型时,会出现request.stream
。
data = request.stream.read()
答案 2 :(得分:14)
我刚遇到这个问题,我想你们中的一些人可能会从我的解决方案中受益。我创建了一个WSGI中间件类,它从套接字中保存原始POST主体。我将值保存在WSGI变量'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
答案 3 :(得分:4)
我终于弄清楚我是否这样做了:
request.environ['CONTENT_TYPE'] = 'application/something_Flask_ignores'
然后request.data
实际上会有帖子数据。这是因为您无法控制客户端请求并希望在服务器上覆盖它。
答案 4 :(得分:0)
这对我有用:
@application.route("/getrawdata", methods=['POST'])
def getrawdata():
#Your processing logic here
return request.get_data()
我已经通过在原始数据中传递二进制字符串在Postman中成功测试了这一点。 为此,您需要在烧瓶中导入请求包:
from flask import request