Получить необработанное тело POST в Python Flask независимо от заголовка Content-Type
Ранее я спрашивал, как получить данные, полученные в запросе Flask, потому что 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
4 ответа
Использование 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
будет казаться пустым в этом случае.
Там в request.stream
когда тип пантомимы не распознается.
data = request.stream.read()
У меня только что была эта проблема, и я думаю, что некоторые из вас могли бы извлечь выгоду из моего решения. Я создал класс промежуточного программного обеспечения WSGI, который сохраняет исходное тело POST из сокета. Я сохранил значение в переменной WSGI 'environment', чтобы в приложении 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
на самом деле будет иметь почтовые данные. Это если вы не можете контролировать запрос клиента и хотите просто переопределить его на сервере.
Это работает для меня:
@application.route("/getrawdata", methods=['POST'])
def getrawdata():
#Your processing logic here
return request.get_data()
Я успешно проверил это в Postman, передав двоичную строку в Raw Data. Чтобы это работало, вам необходимо импортировать пакет запроса в колбу:
from flask import request