Получить необработанное тело 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
 jathanism12 июн. 2012 г., 18:47
Вероятно, это деталь реализации werkzeug, базовой микро-инфраструктуры WSGI, а не Flask.

Ответы на вопрос(4)

Это работает для меня:

@application.route("/getrawdata", methods=['POST'])
def getrawdata():
    #Your processing logic here
    return request.get_data()

Я успешно проверил это в Postman, передав двоичную строку в Raw Data. Чтобы это работало, вам необходимо импортировать пакет запроса в колбу:

from flask import request

У меня только что была эта проблема, и я думаю, что некоторые из вас могли бы извлечь выгоду из моего решения. Я создал класс промежуточного программного обеспечения WSGI, который сохраняет исходное тело POST из сокета. Я сохранил значение в переменной WSGI «Environment». так что я мог бы ссылаться на него как на request.environ ['body_copy & apos;] в моем приложении Flask.

Вы должны быть осторожны, чтобы данные не были слишком большими, иначе у вас могут быть проблемы с памятью на вашем сервере.

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
 02 янв. 2015 г., 21:23
К сожалению, Bottle использует поток запросов, и нет конкретного API, чтобы это исправить, если вы не коснетесь исходного кода. Вот почему я лично перешел на Сокол.
 22 мар. 2013 г., 22:50
Это только хорошее решение, если вы не можете контролировать заголовок Content-Type клиента. Если вы можете изменить это, то ответ ниже бесконечно проще и проще.
 27 февр. 2014 г., 22:56
Я работаю с ненадлежащим клиентом. (У меня нет контроля над клиентом.) Клиент отправляет Content-Type: application / x-www-form-urlencoded, но полезная нагрузка является необработанным XML. Flask расшифровывает его как форму, но дает ключ как «xml version». Это решение работает для меня, чтобы получить данные без попыток Flask разобрать их.

Там & APOS; srequest.stream когда тип пантомимы не распознается.

data = request.stream.read()
 29 нояб. 2012 г., 03:31
Я прочитал комментарий Армина Ронахера, что если вы используетеrequest.json, request.dataи т. д. тогдаrequest.stream будет пустым (или частично потребленным). Я не могу найти комментарий, но, основываясь на этом анекдоте, буду осторожен.
 ddinchev12 июн. 2012 г., 18:26
Но будет ли request.stream.read () возвращать что-либо в тех случаях, когда распознается тип mime?
 13 июн. 2012 г., 07:08
Документация не говорит, а я не знаю. Я думаю, нет, потому что вы можете прочитать поток только один раз.
 14 июл. 2017 г., 07:44
Обновленные документы:werkzeug.pocoo.org/docs/latest/wrappers/… Скажите, что поток всегда доступен, если не разобран в форму.
Решение Вопроса

использование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 будет казаться пустым в этом случае.

 17 мар. 2016 г., 20:34
Кажется, что это нарушается при использовании raven-python (Sentry), ошибок и обходных путей здесь:github.com/getsentry/raven-python/issues/457
 27 авг. 2014 г., 13:07
Вероятно, это должен быть принятый ответ сейчас, когда библиотека изменилась.
 27 июн. 2016 г., 15:09
Может кто-нибудь сделать это вменяемым или документировать это где-нибудь, пожалуйста? Сейчас я прыгаю по сообщениям Stackoverflow, которые говорят что-то еще.
 26 янв. 2016 г., 18:40
Ftr: упомянутыйsource lives here.
 14 апр. 2015 г., 11:41
Очень нелогичное поведение, кстати. Как ошибка.

Ваш ответ на вопрос