Zuvor fragte ich Wie erhalte ich Daten in Flask-Anfrage , weil request.data
leer war. In der Antwort wurde erklärt, dass request.data
der unformatierte Post-Body ist, aber leer sein wird, wenn Formulardaten analysiert werden. Wie kann ich den rohen Post-Body unbedingt bekommen?
@app.route('/', methods=['POST'])
def parse_request():
data = request.data # empty in some cases
# always need raw data here, not parsed form data
Verwenden Sie request.get_data()
, um die Rohdaten unabhängig vom Inhaltstyp abzurufen. Die Daten werden zwischengespeichert und Sie können nach Belieben auf request.data
, request.json
, request.form
zugreifen.
Wenn Sie zuerst auf request.data
zugreifen, wird get_data
mit einem Argument aufgerufen, um zuerst Formulardaten zu parsen. Wenn die Anforderung einen Formularinhaltstyp hat (multipart/form-data
, application/x-www-form-urlencoded
oder application/x-url-encoded
), werden die Rohdaten verbraucht. request.data
und request.json
erscheinen in diesem Fall leer.
Es gibt request.stream
, wenn der Mime-Typ nicht erkannt wird.
data = request.stream.read()
Ich hatte gerade dieses Problem, und ich glaube, einige von Ihnen könnten von meiner Lösung profitieren. Ich habe eine WSGI-Middleware-Klasse erstellt, die den rohen POST -Körper aus dem Socket speichert. Ich habe den Wert in der WSGI-Variablen 'environ' gespeichert, damit ich ihn in meiner Flask-App als request.environ ['body_copy'] bezeichnen kann.
Sie müssen darauf achten, dass die Postdaten nicht zu groß sind oder dass auf Ihrem Server Speicherprobleme auftreten können.
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
Ich habe endlich herausgefunden, ob ich das mache:
request.environ['CONTENT_TYPE'] = 'application/something_Flask_ignores'
Dann hat request.data
tatsächlich die Postdaten. Dies ist der Fall, wenn Sie die Clientanforderung nicht steuern können und sie einfach auf dem Server überschreiben möchten.
Das funktioniert für mich:
@application.route("/getrawdata", methods=['POST'])
def getrawdata():
#Your processing logic here
return request.get_data()
Ich habe dies in Postman erfolgreich getestet, indem ich in Raw Data eine binäre Zeichenfolge übergeben habe. Damit dies funktioniert, müssen Sie das Anforderungspaket in die Flasche importieren:
from flask import request