POST リクエストを一言でいうと
fetch の POST リクエストは、
「ブラウザからサーバーに“データを送る”ための HTTP 通信」 です。
GET が「取りに行く」だとしたら、
POST は「渡しに行く」。
フォームの送信、ユーザー登録、ログイン、コメント投稿など、
「何かをサーバー側に保存してほしい」ときは、ほぼ必ず POST が関わります。
まずは「fetch で POST」の最小パターンを押さえる
一番シンプルな POST リクエスト(JSON を送る)
よく使う形から先に見てしまいましょう。
async function createUser() {
const user = {
name: "Taro",
email: "taro@example.com",
};
const response = await fetch("https://example.com/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(user),
});
const data = await response.json();
console.log("サーバーからの返事:", data);
}
JavaScriptここで重要なポイントは 3 つです。
method: "POST"
→ 「これは POST リクエストですよ」とサーバーに伝えている。
headers: { "Content-Type": "application/json" }
→ 「これから送るデータは JSON 形式ですよ」とサーバーに伝えている。
body: JSON.stringify(user)
→ JavaScript のオブジェクトを JSON 文字列に変換して、リクエストの中身として送っている。
この 3 点さえ押さえれば、
「fetch で JSON を POST する」という基本はクリアです。
なぜ JSON.stringify が必要なのか
JavaScript のオブジェクトはそのままでは送れない
body にそのままオブジェクトを渡したくなりますが、これはダメです。
// これは NG(多くの場合、意図通りにならない)
body: { name: "Taro", email: "taro@example.com" }
JavaScriptHTTP の世界では、
リクエストの「中身(ボディ)」は基本的に「文字列」や「バイナリ」です。
JavaScript のオブジェクトは、そのままでは送れません。
そこで使うのが JSON.stringify です。
const user = { name: "Taro", email: "taro@example.com" };
const json = JSON.stringify(user);
console.log(json); // {"name":"Taro","email":"taro@example.com"}
JavaScriptこの文字列を body に入れます。
body: JSON.stringify(user)
JavaScriptさらに、
「これは JSON ですよ」とサーバーに伝えるために、Content-Type: application/json ヘッダーを付けます。
headers: {
"Content-Type": "application/json",
}
JavaScriptここが重要です。
POST で JSON を送るときは、「オブジェクト → JSON 文字列」に変換し、
ヘッダーで「これは JSON です」と宣言する、という 2 ステップが必須 です。
async / await での POST の流れを丁寧に追う
1. fetch が返すのは「レスポンスそのもの」ではなく Promise
fetch を呼ぶと、すぐにレスポンスが返ってくるわけではありません。
返ってくるのは「レスポンスがそのうち届きますよ」という約束(Promise)です。
const responsePromise = fetch("https://example.com/api/users", { ... });
JavaScriptawait を付けることで、
「レスポンスが届くまで一旦待つ」という書き方になります。
const response = await fetch("https://example.com/api/users", { ... });
JavaScriptここで response は Response オブジェクトです。
まだ中身(JSON データ)は取り出していません。
2. response.json() も非同期(ここも await が必要)
レスポンスの中身を JSON として読み取るには、response.json() を呼びます。
const data = await response.json();
JavaScriptここも await が必要です。
なぜなら、レスポンスボディの読み取りも非同期だからです。
つまり、POST の一連の流れはこうなります。
const response = await fetch(url, options); // HTTP レベルのレスポンスが届くまで待つ
const data = await response.json(); // ボディを JSON として読み取るまで待つ
JavaScriptここが重要です。
「fetch → await」「response.json → await」の 2 段階で待つ
というイメージを持っておくと、非同期の流れがかなりスッキリします。
エラー処理をちゃんと入れた POST の基本形
HTTP ステータスを必ずチェックする
fetch は、
ネットワークレベルのエラー(接続できないなど)のときしか reject されません。
サーバーが 400 や 500 を返しても、「一応レスポンスは返ってきた」とみなされて、
Promise は resolve されます。
なので、POST のときも必ず response.ok や response.status をチェックします。
async function createUser(user) {
try {
const response = await fetch("https://example.com/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(user),
});
if (!response.ok) {
// 4xx, 5xx など
throw new Error("HTTP エラー: " + response.status);
}
const data = await response.json();
console.log("作成成功:", data);
return data;
} catch (err) {
console.error("ユーザー作成に失敗しました:", err);
throw err;
}
}
JavaScriptここでのポイントは、
if (!response.ok) { throw ... } で「HTTP エラー」を自分で投げているcatch でログを取り、必要なら上に再送出している
という 2 点です。
ここが重要です。
POST のときも GET と同じく、「HTTP ステータスを見て、自分でエラーを投げる」パターンを習慣にすると、
エラー処理の設計が一気にやりやすくなります。
フォーム入力を POST する実践的な例
画面のフォームから値を取り、JSON で送る
よくある「ユーザー登録フォーム」をイメージしてみましょう。
HTML 側がこんな感じだとします。
<form id="signup-form">
<input id="name" type="text" placeholder="名前" />
<input id="email" type="email" placeholder="メールアドレス" />
<button type="submit">登録</button>
</form>
これを JavaScript で拾って、POST します。
const form = document.getElementById("signup-form");
form.addEventListener("submit", async (event) => {
event.preventDefault(); // 画面遷移を止める
const name = document.getElementById("name").value;
const email = document.getElementById("email").value;
const user = { name, email };
try {
const response = await fetch("https://example.com/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(user),
});
if (!response.ok) {
throw new Error("HTTP エラー: " + response.status);
}
const data = await response.json();
alert("登録に成功しました! ID: " + data.id);
} catch (err) {
console.error(err);
alert("登録に失敗しました。時間をおいて再度お試しください。");
}
});
JavaScript流れを整理すると、
フォーム送信イベントをキャッチする
ブラウザ標準の送信(画面遷移)を止める
入力値を取り出してオブジェクトにする
JSON にして POST する
ステータスをチェックし、OK なら JSON を読む
成功ならユーザーに成功メッセージ、失敗ならエラーメッセージ
という形です。
ここが重要です。
「画面の入力 → オブジェクト → JSON → POST → レスポンス JSON → 画面に反映」
という一連の流れを、自分の中で一本の線としてイメージできるようになると、
API 通信が一気に“怖くなく”なります。
application/x-www-form-urlencoded で送る場合(知識として)
いわゆる「フォーム形式」で送るパターン
サーバー側が「JSON じゃなくて、フォーム形式で送ってね」という場合もあります。
そのときは URLSearchParams を使うことが多いです。
const params = new URLSearchParams();
params.append("name", "Taro");
params.append("email", "taro@example.com");
const response = await fetch("https://example.com/api/users", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: params.toString(),
});
JavaScriptただ、最近の API は JSON を受け取ることが多いので、
初心者のうちは「まずは JSON で送るパターン」をしっかり押さえれば十分です。
ファイルを含む POST(FormData)の入り口だけ触れておく
画像アップロードなどは FormData を使う
画像やファイルを一緒に送りたい場合は、FormData を使うのが定番です。
const formData = new FormData();
formData.append("name", "Taro");
formData.append("avatar", fileInput.files[0]); // <input type="file" id="avatar" />
const response = await fetch("https://example.com/api/profile", {
method: "POST",
body: formData,
});
JavaScriptこのときは、Content-Type を自分で書かないのがポイントです。
ブラウザが自動で適切な multipart/form-data を付けてくれます。
ここは少し応用なので、
「JSON での POST に慣れてきたら触る」くらいの感覚で OK です。
初心者として「POST リクエスト」で本当に押さえてほしいこと
fetch で POST するときは、method: "POST" を必ず指定する。
JSON を送るときは、
オブジェクトを JSON.stringify で文字列に変換し、Content-Type: application/json を付ける。
await fetch(...) でレスポンスを待ち、await response.json() で中身を JSON として読む。
この「2 段階 await」のイメージを持つ。
response.ok や response.status を必ずチェックし、
エラー時は自分で throw して try / catch で扱う。
フォーム送信と組み合わせるときは、
「入力 → オブジェクト → JSON → POST → レスポンス → 画面反映」という一本の流れを意識する。
そして何より、
「POST は“サーバーに何かを渡す”ためのもの」
「JSON.stringify と Content-Type がセット」
この 2 つが頭に入っていれば、
あとはパターンを少しずつ増やしていくだけで、
かなり実戦的な API 通信が書けるようになります。
