[英]Get raw POST body in Python Flask regardless of Content-Type header
Previously, I asked How to get data received in Flask request because request.data
was empty.之前问过如何获取 Flask 请求中收到的数据,因为
request.data
为空。 The answer explained that request.data
is the raw post body, but will be empty if form data is parsed.答案解释说
request.data
是原始帖子正文,但如果解析表单数据,它将为空。 How can I get the raw post body unconditionally?如何无条件获取原始帖子正文?
@app.route('/', methods=['POST'])
def parse_request():
data = request.data # empty in some cases
# always need raw data here, not parsed form data
Use request.get_data()
to get the raw data, regardless of content type.无论内容类型如何,都使用
request.get_data()
获取原始数据。 The data is cached and you can subsequently access request.data
, request.json
, request.form
at will.数据被缓存,随后您可以随意访问
request.data
、 request.json
、 request.form
。
If you access request.data
first, it will call get_data
with an argument to parse form data first.如果您首先访问
request.data
,它将首先调用带有参数的get_data
来解析表单数据。 If the request has a form content type ( multipart/form-data
, application/x-www-form-urlencoded
, or application/x-url-encoded
) then the raw data will be consumed.如果请求具有表单内容类型(
multipart/form-data
、 application/x-www-form-urlencoded
或application/x-url-encoded
),则将使用原始数据。 request.data
and request.json
will appear empty in this case.在这种情况下
request.data
和request.json
将显示为空。
request.stream
is the stream of raw data passed to the application by the WSGI server. request.stream
是 WSGI 服务器传递给应用程序的原始数据流。 No parsing is done when reading it, although you usually want request.get_data()
instead.读取时不进行解析,尽管您通常需要
request.get_data()
代替。
data = request.stream.read()
The stream will be empty if it was previously read by request.data
or another attribute.如果之前由
request.data
或其他属性读取,则该流将为空。
I created a WSGI middleware that stores the raw body from the environ['wsgi.input']
stream.我创建了一个 WSGI 中间件,用于存储来自
environ['wsgi.input']
流的原始正文。 I saved the value in the WSGI environ so I could access it from request.environ['body_copy']
within my app.我将值保存在 WSGI 环境中,以便我可以从我的应用程序中的
request.environ['body_copy']
访问它。
This isn't necessary in Werkzeug or Flask, as request.get_data()
will get the raw data regardless of content type, but with better handling of HTTP and WSGI behavior.这在 Werkzeug 或 Flask 中不是必需的,因为
request.get_data()
将获取原始数据而不管内容类型如何,但可以更好地处理 HTTP 和 WSGI 行为。
This reads the entire body into memory, which will be an issue if for example a large file is posted.这会将整个正文读入内存,如果例如发布大文件,这将是一个问题。 This won't read anything if the
Content-Length
header is missing, so it won't handle streaming requests.如果缺少
Content-Length
标头,这将不会读取任何Content-Length
,因此它不会处理流请求。
from io import BytesIO
class WSGICopyBody(object):
def __init__(self, application):
self.application = application
def __call__(self, environ, start_response):
length = int(environ.get('CONTENT_LENGTH') or 0)
body = environ['wsgi.input'].read(length)
environ['body_copy'] = body
# replace the stream since it was exhausted by read()
environ['wsgi.input'] = BytesIO(body)
return self.application(environ, start_response)
app.wsgi_app = WSGICopyBody(app.wsgi_app)
request.environ['body_copy']
request.data
will be empty if request.headers["Content-Type"]
is recognized as form data, which will be parsed into request.form
.如果
request.headers["Content-Type"]
被识别为表单数据, request.data
将为空,它将被解析为request.form
。 To get the raw data regardless of content type, use request.get_data()
.无论内容类型如何,都要获取原始数据,请使用
request.get_data()
。
request.data
calls request.get_data(parse_form_data=True)
, which results in the different behavior for form data. request.data
调用request.get_data(parse_form_data=True)
,这导致表单数据的不同行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.