POST のリクエストを組み立てる
このレッスンで分かること
fetchの第 2 引数にmethodとheadersとbodyを組み立てます- 新しく作るのか、すでにあるものを直すのかで、送り先が変わります
送ったのに、中身が [object Object] で届く
データを送るときにいちばん多い事故がこれです。body にオブジェクトをそのまま入れると、文字列に変換されて 15 文字だけが相手に届きます。
JavaScript
const comment = { body: "はじめまして", year: 2026 };
console.log(String(comment)); // [object Object]
console.log(JSON.stringify(comment)); // {"body":"はじめまして","year":2026}
console.log(typeof JSON.stringify(comment)); // stringJSON.stringify はオブジェクトを JSON の文字列に変えます。受け取ったサーバー側は、この文字列を JSON として読み直します。取ってくるときに使った response.json() と対になっていて、送るときに文字列へ畳み、受け取るときに文字列から戻しているだけです。
このコースでは、実際に送信するところは扱いません。教材から本物の書き込みを飛ばすと、課題を解くたびにどこかのサーバーのデータが増えていくことになるからです。練習用の口も読み取り専用にしてあります。ここでやるのは、送る直前までの組み立てです。実務で詰まるのもほとんどこの部分で、組み立てさえ間違えなければ、送信そのものは 1 行足すだけです。
3 点セットで、どう送るかを決める
fetch は 2 つ目の引数にオブジェクトを取ります。ここに送りかたを書きます。
JavaScript
const options = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(comment)
};| 項目 | 何を決めるか | 書き忘れるとどうなるか |
|---|---|---|
method | 取るのか作るのか消すのか | GET として送られ、本文が捨てられる |
headers | 本文の形式は何か | サーバーが JSON として読んでくれない |
body | 送る中身そのもの | 中身のないリクエストになる |
headers の役割は名乗ることです。文字列の形と、それを何として読むかの宣言は、両方そろって初めて意味を持ちます。取ってくるだけの GET なら、第 2 引数ごと省けます。送る中身が無いからです。
新しく作るのか、直すのかで送り先が変わる
URL は名詞で、したいことはメソッドで表す。この決めかたがそのまま効いてきます。同じ「保存する」でも、新しく作るのか、すでにあるものを直すのかで送り先もメソッドも変わります。
JavaScript
const base = "https://yumesaku.tech/course-api/";
// 新しく足す。番号はサーバーが決めるので、一覧を指す
// POST base + "comments.json"
// 3 番を置き換える。相手が決まっているので、その 1 件を指す
// PUT base + "comments/3.json"新規作成のときは、まだ番号が決まっていません。番号を決めるのはサーバーの仕事です。だから送り先は一覧を指す URL になり、この一覧に 1 件足してください、という意味になります。存在しない番号の URL へ送ると 404 が返ります。
どちらなのかは、送るデータが番号を持っているかどうかで決めます。ここで気を付けたいのが if の書きかたです。
JavaScript
// 番号が 0 のときに新規扱いになってしまう
if (comment.id) { }
// 型で見れば 0 も番号として扱える
if (typeof comment.id === "number") { }返ってきた返事の読みかたは、取るときとまったく同じです。response.ok で分け、中身は response.json() で取り出します。新規作成が成功したときは 201 が返ることがよくありますが、ok は 200 から 299 で true になるので、そのまま成功として扱えます。
よくある間違い
headersを付け忘れる — 中身は JSON なのに、そう名乗っていない状態です。相手が読み方を決められず、送った中身がまるごと無視されることがあります- 新規作成なのに、番号付きの URL へ送る — まだ存在しない番号を指しているので 404 が返ります。新しく足すときの送り先は、いつでも一覧のほうです
要件
- buildWorkRequest(work) は { url, method, headers, body } を返す
- work.id が数値なら method は PUT で、url は https://yumesaku.tech/course-api/works/
.json にする - work.id が無ければ method は POST で、url は https://yumesaku.tech/course-api/works.json にする
- headers は
{ "Content-Type": "application/json" }、body は work を JSON.stringify したものにする - work が null のとき、または title が文字列でないか空のときは null を返す
入出力例
buildWorkRequest({"title":"学習ログ","year":2026}) → {"body":"{\"title\":\"学習ログ\",\"year\":2026}","headers":{"Content-Type":"application/json"},"method":"POST","url":"https://yumesaku.tech/course-api/works.json"}
buildWorkRequest({"id":3,"title":"スキル一覧の表","year":2026}) → {"body":"{\"id\":3,\"title\":\"スキル一覧の表\",\"year\":2026}","headers":{"Content-Type":"application/json"},"method":"PUT","url":"https://yumesaku.tech/course-api/works/3.json"}
buildWorkRequest({"tags":["JavaScript","fetch"],"title":"作品ギャラリー"}) → {"body":"{\"tags\":[\"JavaScript\",\"fetch\"],\"title\":\"作品ギャラリー\"}","headers":{"Content-Type":"application/json"},"method":"POST","url":"https://yumesaku.tech/course-api/works.json"}
buildWorkRequest({"title":""}) → null
buildWorkRequest(null) → null