はじめに
個人で技術検証をしていて、React から Django の API を呼ぶところで、2回エラーにぶつかりました。どちらも画面上は「API エラー」でしたが、1回目は 502、2回目は 400 で、原因はまったく別のところにありました。
この記事では、2つのエラーで何が起きていたのかと、エラーの数字から探す場所をどう絞ったかを書きます。React や Django を触り始めた人、Docker で開発環境を作り始めた人の参考になればうれしいです。
この記事のまとめ
- 502 は「たどり着けない」:リクエストが Django まで届いていない
- 400 は「届いたけど断られた」:Django には届いていて、そのうえで断られている
環境
- フロントエンド:Vite + React 19 + TypeScript(Node.js 22)
- バックエンド:Django 6.1
- 構成:React の画面から
/api/...を呼び、Vite のプロキシで Django に転送する - 2回目の時点では、Docker Compose で Django と Vite を起動
- 開発は Claude Code と一緒に進めています
1つ目:502 エラー(たどり着けない)
何が起きたか
React の画面から Django の API を呼んだら、502 エラーになりました。Django を直接呼ぶと成功するのに、React の画面から Vite を経由すると失敗する、という状態です。
どう絞り込んだか
「直接なら成功、経由だと失敗」なので、Django そのものではなく、Vite から Django へ転送する区間に問題があると分かります。区間を分けて確かめるだけで、探す場所がぐっと絞れました。
原因
Node.js では localhost が IPv6 の ::1 として解決されるのに、Django は IPv4 の 127.0.0.1 で待ち受けていました。Vite の転送先に localhost と書いていたため、Django がいない場所にリクエストを送っていたことになります。
対処
Vite のプロキシの転送先を、localhost ではなく http://127.0.0.1:8000 に変えて解決しました。
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8000', // localhost から変更
},
},
},
})
この原因は、Claude Code がエラーログから見つけて、修正と再確認までしてくれました。
「localhost と書いておけば大丈夫」という思い込みは危ない、というのが一番の学びでした。
2つ目:400 エラー(届いたけど断られた)
何が起きたか
検証環境を Docker で動くようにしたあと、画面に「API エラー: 400」と表示されました。
最初は、1つ目と同じように「つながっていないのかな」と思いました。でも実際は、リクエストは Django まで届いていて、そのうえで Django に断られていました。
原因
Django には、受け付けるリクエストの宛先を決めておく ALLOWED_HOSTS という設定があります。一覧にない宛先からのリクエストは、400 で断られます。
この一覧に、Docker でのサービス名である backend が入っていませんでした。Docker にしたことで、Django から見たリクエストの宛先が変わっていたわけです。
対処
ALLOWED_HOSTS に backend を追加して解決しました。
ALLOWED_HOSTS = ["localhost", "127.0.0.1", "backend"]
502 と 400 の違い
どちらも画面上は同じ「API エラー」でしたが、意味はまったく違いました。
| 502 | 400 | |
|---|---|---|
| ひとことで | たどり着けない | 届いたけど断られた |
| リクエストは Django に届いたか | 届いていない | 届いている |
| 探す場所 | Django までの経路(プロキシの転送先など) | Django 側の設定や、送った内容 |
| 今回の原因 |
localhost が IPv6 で解決され、IPv4 で待つ Django に届かなかった |
ALLOWED_HOSTS に Docker のサービス名がなかった |
学んだこと
エラーの数字をちゃんと読む。 502 なら「途中で止まっている」、400 なら「相手には届いている」。数字の意味を知っているだけで、探す場所が半分くらいに絞れます。今回の 400 も、数字の意味を知っていれば「つながっていない」と勘違いせずに済みました。
区間を分けて確かめる。 「直接なら成功、経由だと失敗」のように、どこまでは動いているかを確かめると、原因のある区間が見えてきます。
AI に直してもらっても、理由は自分で理解する。 502 の原因は Claude