ざっくりまとめ
jsからaxiosを用いたPOSTリクエストでBASE64形式の画像データを'multipart/form-data'として送ってFlaskで受け取ろうとしました。
しかし、 400 BAD REQUESTが出ました。
「BASE64をバイナリ形式経由でfile形式にすること」と「送るデータのnameと受け取るデータのnameを一致させること」をして解決しました。
目次
- はじめに
- やろうとしたこと
- コード
- 今回詰まったエラー
- 思考
- 参考にさせていただいたサイト
1. はじめに
エラーで詰まったときは備忘録として記事に残しておこう、ということで第一弾です(第一弾で終わりそう。。。)。
先日、ハッカソンに参加してきまして、今回はその時に詰まったエラーについて書いていきます。
(ちなみに今回jsとかaxiosとかNext.jsとか諸々初めて触れたので、内容に間違いがあったら優しく教えて欲しいです。)
先に結論を言ってしまうと、簡単なミスでした()
2. やろうとしたこと
フロントエンド:Next.js
バックエンド:Flask(Herokuを用いてデプロイ)
BASE64形式の画像データをファイル形式でaxiosを用いてPOSTで送って、Flaskで受け取る。
3. コード
js側
const image = BASE64形式の画像データ
const data = new FormData();
data.append('file', image);
const postImageUri = 'ポスト先のURL'
axios({
method: "POST",
url: postImageUri,
data: data,
headers: {"Content-Type": "multipart/form-data", "Access-Control-Allow-Origin": "*"},
})
.then(res => {
})
.catch(err => {
})
flask側
@app.route("/analyze", methods=["POST"])
def analyze():
request_image = request.files['image_file']
...
return
4. 今回詰まったエラー
POST (URL) 400 (BAD REQUEST)
これだけ。。。。。。
コンソールのエラーの詳細を見てもエラーの詳細はなく、Herokuのログを見てもそれらしいものもない。。。
ここまで長かったですが、今回はこのどこでエラーを吐いてんのか分からんエラーをなんとかするという話です。
5. 思考
まず知識が浅いこともあり、エラーと相対して、
「400 BAD REQUEST!?。。。ってなんだ。。?」
となってみたので、少し調べてみました(参考文献1)。
それによると、リクエストが悪いぞ!とのこと
という訳で、画像データがファイル形式になっていないのでは?と考え、さらに色々と調べました。
その結果、BASE64形式をバイナリ形式経由でfile形式に変換することで解決しました(方法については参考文献2に記載されているものを使用させていただきました)。
その結果がこちら
POST (URL) 400 (BAD REQUEST)
解決してないやーん
前進した気はするのですが。。。
と、ここでまたすごい時間詰まってしまいました。。。
結局、原因は基礎的なとこにありました。
まず、Flask側が悪かったことが判明しました。
Flaskでは、データを
request.files['image_file']
で受け取ろうとしていたのですが、通常この'image_file'という部分はリクエストする側のhtml内のinputのnameの値と一致している必要があります。
今回の場合では、FormDataに追加するところ
data.append('file', image); // ココダヨ
の'file'と一致している必要がありました。(灯台下暗し)
という訳で最初のjs側のコードに最初のエラー解決法を加え、'file'を'image_file'に変更することでうまくいきました!
6. 参考にさせていただいたサイト
-
「400 Bad Request」エラーの解決方法(原因と対策) (https://kinsta.com/jp/knowledgebase/400-bad-request/ )
-
Base64形式のデータをFileオブジェクトに変換する (https://gray-code.com/javascript/convert-base64-format-data-to-file-object/ )