Auparavant, je demandais Comment obtenir les données reçues dans la demande Flask parce que request.data
était vide. La réponse a expliqué que request.data
est le corps de publication brut, mais sera vide si les données du formulaire sont analysées. Comment puis-je obtenir le post corps brut sans condition?
@app.route('/', methods=['POST'])
def parse_request():
data = request.data # empty in some cases
# always need raw data here, not parsed form data
Utilisez request.get_data()
pour obtenir les données brutes, quel que soit le type de contenu. Les données sont mises en cache et vous pouvez ensuite accéder à request.data
, request.json
, request.form
à volonté.
Si vous accédez d'abord à request.data
, il appellera get_data
avec un argument pour analyser les données de formulaire en premier. Si la demande a un type de contenu de formulaire (multipart/form-data
, application/x-www-form-urlencoded
ou application/x-url-encoded
), les données brutes seront consommées. request.data
et request.json
apparaîtront vides dans ce cas.
Il y a request.stream
lorsque le type MIME n'est pas reconnu.
data = request.stream.read()
Je viens d'avoir ce problème, et je pense que quelques-uns d'entre vous pourraient bénéficier de ma solution. J'ai créé une classe de middleware WSGI qui enregistre le corps brut POST du socket. J'ai enregistré la valeur dans la variable WSGI «environ» afin de pouvoir y faire référence sous le nom de request.environ ['body_copy'] dans mon application Flask.
Veillez à ce que les données de publication ne soient pas trop volumineuses, sinon vous pourriez avoir des problèmes de mémoire sur votre serveur.
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
J'ai finalement compris si je fais ça:
request.environ['CONTENT_TYPE'] = 'application/something_Flask_ignores'
Alors request.data
aura réellement les données de publication. Cela se produit si vous ne pouvez pas contrôler la demande du client et souhaitez simplement la remplacer sur le serveur.
Cela fonctionne pour moi:
@application.route("/getrawdata", methods=['POST'])
def getrawdata():
#Your processing logic here
return request.get_data()
J'ai testé cela avec succès dans Postman en passant une chaîne binaire dans Raw Data. Pour que cela fonctionne, vous devez importer le package de demande dans la fiole:
from flask import request