ちょっとはハマったので、情報共有
環境
- Flask 1.0.2
- curl 7.54.0
結論
FlaskでPOSTされたデータをそのまま受け取るときはrequest.data
ではなくrequest.get_data()
を使う
理由
-
request.data
: HTTPヘッダのContent-typeがハンドリングできないと値が格納されない。 -
request.get_data()
: Content-typeの値にかかわらず値を取得できる。
実験
request.get_data()を使った場合
request.get_data()をそのまま返すサーバを立てる
from flask import Flask, request
app = Flask(__name__)
@app.route('/',methods=["POST"])
def hoge():
return request.get_data()
app.run()
POSTのBODYに{"a":1}
を指定してリクエスト
$ curl -X POST -d '{"a":1}' http://127.0.0.1:5000/
{"a":1}
# ↑POSTしたデータが帰ってくる
POSTしたデータが帰ってくるため、上手く動いている。
request.dataを使った場合
request.dataをそのまま返すサーバを立てる
from flask import Flask, request
app = Flask(__name__)
@app.route('/',methods=["POST"])
def hoge():
return request.data
app.run()
POSTのBODYに{"a":1}
を指定してリクエスト
$ curl -X POST -d '{"a":1}' http://127.0.0.1:5000/
# 何も返ってこない
POSTしたデータが返ってこない。
理由はcurlのデフォルトのContent-typeがapplication/x-www-form-urlencoded
であり、これがFalskがハンドリングできる値ではないため。
なので、curlに明示的にContent-type: application/json
を指定すれば、
$ curl -X POST -H "Content-type: application/json" -d '{"a":1}' http://127.0.0.1:5000/
{"a":1}
# ↑POSTしたデータが返ってくる
マニュアルにも書いてある
Contains the incoming request data as string in case it came with a mimetype Werkzeug does not handle.