以前は、request.data
が空だったため、 Flaskリクエストで受信したデータを取得する方法 を要求しました。回答では、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
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
は、WSGIサーバーによってアプリケーションに渡される生データのストリームです。通常はrequest.get_data()
が代わりに必要ですが、読み取るときに解析は行われません。
data = request.stream.read()
以前にrequest.data
または別の属性によって読み取られた場合、ストリームは空になります。
environ['wsgi.input']
ストリームから生のボディを格納するWSGIミドルウェアを作成しました。 WSGI環境に値を保存して、アプリ内のrequest.environ['body_copy']
からアクセスできるようにしました。
request.get_data()
はコンテンツタイプに関係なく生データを取得するため、これはWerkzeugやFlaskでは必要ありませんが、HTTPおよびWSGI動作の処理が向上します。
これにより、本文全体がメモリに読み込まれます。これは、たとえば大きなファイルが投稿される場合に問題になります。 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
がフォームデータとして認識され、request.headers["Content-Type"]
に解析される場合、request.form
は空になります。コンテンツタイプに関係なく生データを取得するには、request.get_data()
を使用します。
request.data
はrequest.get_data(parse_form_data=True)
を呼び出します。これにより、フォームデータの動作が異なります。
これは私のために働く:
@application.route("/getrawdata", methods=['POST'])
def getrawdata():
#Your processing logic here
return request.get_data()
Raw Dataにバイナリ文字列を渡すことで、Postmanでこれを正常にテストしました。これを機能させるには、フラスコにリクエストパッケージをインポートする必要があります。
from flask import request