<目次>
Flaskのget_json()で400 Bad Requestエラーが出た時の原因と対処
エラー内容
原因
対策
参考
余談
Flaskのget_json()で400 Bad Requestエラーが出た時の原因と対処
エラー内容
Flaskアプリをローカル実行した状態(http://127.0.0.1:5000)で、設定したエンドポイント(/sample_api/)に対して、PowerShell経由でcurlコマンドからHTTPリクエストを送った際に、下記のエラーが発生しました。
(エラーメッセージ)
<!doctype html>
<html lang=en>
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>The browser (or proxy) sent a request that this server could not understand.</p>
(エラーが出たPOSTリクエスト)
curl.exe --data-binary '{"key":"val"}' -H 'content-type: application/json;' http://127.0.0.1:5000/sample_api/
(エラーが出たプログラム)
import json
from flask import Flask, request
# Flaskクラスのインスタンス生成
app = Flask(__name__)
@app.route('/sample_api/', methods=['GET', 'POST'])
def sample_api():
print("=======", request.data)
print("=======", json.loads(request.data, strict=False))
print("=======", request.get_json())
return "Hello World"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
(図151)PowerShellからcurlコマンドでリクエストを送り、400 Bad Requestエラー

(Flask結果)
127.0.0.1 – – [DD/Mon/YYYY HH:MM:SS] “POST /sample_api/ HTTP/1.1” 400 –
原因
・jsonに含まれる値について、必要なエスケープ処理が出来ていないため、発生している可能性があります(有効なjson形式のデータを渡せていない)
・例えばKeyやValueの値は単にダブルクォート「”」で囲うのみならず、前にバックスラッシュ「\」でエスケープして渡す必要があります。
>目次にもどる
対策
リクエストで送るJSON形式のデータについて、ダブルクォートをエスケープ処理してあげる必要があります。
(修正前)
curl.exe --data-binary '{"key":"val"}' -H 'content-type: application/json;' http://127.0.0.1:5000/sample_api/
(修正後)
curl.exe --data-binary '{\"key\":\"val\"}' -H 'content-type: application/json;' http://127.0.0.1:5000/sample_api/
PowerShellから再度テストすると、今度はレスポンスコード「200」(OK)が返ってきます。
(図152)

(Flask結果)
127.0.0.1 – – [DD/Mon/YYYY HH:MM:SS] “POST /sample_api/ HTTP/1.1” 200 –
参考
・Flaskの公式ドキュメントのget_jsonメソッドの箇所も確認。
・get_json()は内部的にはrequest.dataをJSON形式でパース(構文解析と変換)している
⇒ Flask公式ドキュメント:get_json()
・例えば、敢えてNGなJSON「’{“key”:”val”}’」を入れた場合、パース元のrequest.dataは「b’{key:val}’」となり、ダブルクォートが取り除かれてしまっています。
(図153)

・この結果、get_jsonのパース(構文解析とJSON変換)に失敗していしまい、400 Bad Requestエラーが発生しています。
・一方で、OKなJSON「’{\“key\”:\”val\”}’」を入れた場合、パース元のrequest.dataは「b’{“key”:”val”}’」となり、これはget_json()でも取得可能な形になります。
(図154)

>目次にもどる
余談
request.get_json()
以外にも
import json json.loads(request.data, strict=False)
でも似た処理が可能です。
>目次にもどる