JavaScript | Web API:通信・ネットワーク系 - fetch API

JavaScript JavaScript
スポンサーリンク

fetch は「ブラウザからサーバーにお願いしに行く関数」

まずイメージからいきます。
fetch は、「ブラウザからサーバーに“ちょっとデータください”とか“これ送ります”とお願いしに行くための関数」 です。

ブラウザの中から HTTP リクエスト(GET / POST など)を送って、
サーバーから返ってきたレスポンス(JSON や HTML、テキストなど)を受け取るために使います。

そして fetch非同期 です。
呼んだ瞬間に結果は返ってこなくて、「あとで結果が届くよ」という約束(Promise)を返します。
ここをちゃんと理解できると、一気にプロっぽい書き方に近づきます。


fetch の一番シンプルな形をまず押さえる

基本形:URL を渡して呼ぶ

一番シンプルな形はこうです。

fetch("https://example.com/data.json")
  .then((response) => {
    // レスポンスが返ってきたときの処理
  })
  .catch((error) => {
    // 通信エラーなどが起きたときの処理
  });
JavaScript

fetch に URL を渡すと、
ブラウザがその URL に HTTP リクエストを送ります。

すぐにデータが返ってくるわけではなく、
fetchPromise を返します。

then の中は「レスポンスが返ってきたあとに実行される処理」
catch の中は「ネットワークエラーなどが起きたときの処理」

というイメージです。

async / await で書くともっと読みやすい

最近の書き方だと、async / await を使うことが多いです。

async function loadData() {
  try {
    const response = await fetch("https://example.com/data.json");
    // ここに来た時点でレスポンスは返ってきている
  } catch (error) {
    console.error("通信に失敗しました", error);
  }
}
JavaScript

await fetch(...) と書くと、
「レスポンスが返ってくるまで一旦待つ」という意味になります。
ただし、これは「関数の中で待つ」だけで、ブラウザ全体が止まるわけではありません(非同期)。


fetch のレスポンスを「どう読むか」が超重要

response オブジェクトとは何か

fetch の結果として返ってくるのは、
「レスポンスそのもの」ではなく、Response オブジェクトです。

const response = await fetch("https://example.com/data.json");
JavaScript

この response は、
ステータスコード(200, 404 など)やヘッダー、
そして「ボディ(中身)をどう読むか」のメソッドを持っています。

例えば、こういうプロパティがあります。

console.log(response.ok);        // true / false(200台なら true)
console.log(response.status);    // 200, 404 など
console.log(response.statusText); // "OK", "Not Found" など
JavaScript

JSON を読むときの定番パターン

API から JSON が返ってくるケースが一番多いので、
ここをしっかり押さえましょう。

async function loadUser() {
  const response = await fetch("https://example.com/api/user");

  if (!response.ok) {
    // ステータスコードが 200台以外ならエラー扱いにする
    throw new Error(`HTTP error: ${response.status}`);
  }

  const data = await response.json();
  console.log(data);
}
JavaScript

ここで重要なポイントがいくつかあります。

response.ok を必ず見る
fetch 自体は「HTTP 404 でもエラーにしない」
「通信は成功したけど、サーバーが 404 を返した」状態を自分で判定する必要がある

response.json() も非同期
ボディを JSON としてパースする処理も時間がかかるので、
これも await で待つ必要がある

つまり、流れとしてはこうです。

  1. await fetch(...) でレスポンスヘッダーまで取得
  2. ステータスコードをチェック
  3. 問題なければ await response.json() でボディを JSON として読む

この「二段階で読む」感覚がとても大事です。

テキストとして読みたいとき

JSON ではなく、プレーンテキストを読みたいときは response.text() を使います。

const response = await fetch("/hello.txt");
const text = await response.text();
console.log(text);
JavaScript

HTML や CSV など、「とりあえず文字列として扱いたい」ものは text() で読みます。


GET だけじゃない:POST などのメソッドも使える

POST で JSON を送る基本形

fetch は GET だけでなく、
POST / PUT / DELETE なども送れます。

よく使うのは「JSON を POST する」パターンです。

async function createUser(user) {
  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 error: ${response.status}`);
  }

  const data = await response.json();
  console.log("作成されたユーザー:", data);
}
JavaScript

ここでの重要ポイントは、

method で HTTP メソッドを指定する
headers でヘッダーを指定する(JSON を送るなら Content-Type: application/json
body に送信するデータを文字列として入れる(JSON.stringify する)

というところです。

fetch の第2引数は「オプションオブジェクト」で、
ここにメソッドやヘッダー、ボディなどをまとめて指定します。

フォームデータを送る場合

フォームの内容をそのまま送るときは、FormData を使うこともできます。

const form = document.querySelector("form");
const formData = new FormData(form);

const response = await fetch("/submit", {
  method: "POST",
  body: formData,
});
JavaScript

この場合、Content-Type はブラウザが自動で付けてくれます。
ファイルアップロードなどにも使われるパターンです。


fetch の「エラー」の考え方が少しややこしい

fetch が throw するのは「ネットワークレベルの失敗」だけ

ここが初心者が一番ハマりやすいポイントです。

fetchcatch に来るのは、
「ネットワークレベルで失敗したときだけ」 です。

例えば、

インターネットにつながっていない
DNS が引けない
CORS でブロックされた(一部のケース)

などです。

一方で、

サーバーが 404 を返した
サーバーが 500 を返した

といった HTTP エラーは、fetch 的には「成功」扱い です。
Promise は resolve され、response.ok が false になります。

つまり、こう書くと危険です。

try {
  const response = await fetch("/api/user");
  const data = await response.json(); // ここで「成功した」と思い込んでしまう
} catch (e) {
  console.error("エラー", e);
}
JavaScript

404 や 500 のときも catch には来ないので、
自分で response.ok をチェックする必要があります。

正しいパターンを体に染み込ませる

おすすめは、こういうテンプレートを覚えてしまうことです。

async function safeFetchJson(url, options) {
  const response = await fetch(url, options);

  if (!response.ok) {
    throw new Error(`HTTP error: ${response.status}`);
  }

  return response.json();
}
JavaScript

そして、使う側はこう書きます。

async function main() {
  try {
    const user = await safeFetchJson("/api/user");
    console.log(user);
  } catch (error) {
    console.error("取得に失敗しました", error);
  }
}
JavaScript

fetchok チェック → json()」という流れを
一つの関数に閉じ込めてしまうと、
毎回同じミスを繰り返さずに済みます。


具体例:ボタンを押したら API からデータを取ってきて表示する

HTML 側のイメージ

<button id="load">ユーザーを読み込む</button>
<pre id="output"></pre>

JavaScript 側のコード

const button = document.querySelector("#load");
const output = document.querySelector("#output");

async function loadUser() {
  output.textContent = "読み込み中...";

  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/users/1");

    if (!response.ok) {
      output.textContent = `HTTP エラー: ${response.status}`;
      return;
    }

    const user = await response.json();
    output.textContent = JSON.stringify(user, null, 2);
  } catch (error) {
    output.textContent = `通信エラー: ${error.message}`;
  }
}

button.addEventListener("click", () => {
  loadUser();
});
JavaScript

ここでやっていることを整理すると、

ボタンが押されたら loadUser を呼ぶ
fetch でサーバーにリクエストを送る
レスポンスが返ってきたら ok をチェックする
問題なければ json() で中身を読む
結果を画面に表示する
ネットワークエラーなら catch でメッセージを出す

という流れです。

このくらいのコードがスラスラ書けるようになると、
「フロントエンドから API を叩く」という基本がかなり身についてきます。


fetch を使うときに初心者が意識しておくといいこと

「非同期である」という感覚をちゃんと持つ

fetch は呼んだ瞬間に結果が返ってくるわけではありません。
「今すぐ結果が欲しい」のではなく、
「結果が返ってきたときに何をするか」を書く ものです。

await を使うと見た目は「同期っぽく」書けますが、
実際には「その関数の中だけ一旦待つ」だけで、
ブラウザ全体は他のことを続けています。

この「時間差で結果が返ってくる」感覚を、
fetch を通して体に馴染ませていくと、
非同期処理全体への理解が深まります。

「エラーの種類」を分けて考える

fetch まわりのエラーは、大きく分けて二種類あります。

ネットワークレベルのエラー(fetch が reject する)
HTTP レベルのエラー(404, 500 など。response.ok が false)

この二つをちゃんと分けて扱えるようになると、
エラーハンドリングの設計が一気にきれいになります。

例えば、

ネットワークエラー
「通信できませんでした。ネットワークを確認してください」

HTTP 404
「データが見つかりませんでした」

HTTP 500
「サーバー側でエラーが起きています」

のように、ユーザーへのメッセージも変えられます。


まとめ:fetch を「ただの関数」ではなく「会話の窓口」として捉える

最後に、頭の中に置いておいてほしいイメージです。

fetch は、
「ブラウザ(あなたのコード)とサーバーが会話するための窓口」 です。

URL に向かって「こういうリクエストを送りたい」と伝える
サーバーから「こういうレスポンスが返ってきたよ」と受け取る
その結果を画面に反映したり、次の処理につなげたりする

その一連の流れの入口が fetch です。

だからこそ、

レスポンスをどう読むか(json() / text()
エラーをどう扱うか(ok チェック / catch
どのタイミングで呼ぶか(ボタン、ページロードなど)

を意識して書けるようになると、
「API と会話できるフロントエンドエンジニア」に一歩近づきます。

もしよければ、
まずは「ボタンを押したら JSON を取ってきて画面に表示する」
という小さなサンプルを、自分の手で書いてみてください。
そこから、POST やエラーハンドリングを少しずつ足していくと、
fetch がただの難しい関数ではなく、「頼れる相棒」に変わっていきます。

タイトルとURLをコピーしました