コンテンツにスキップ

JavaScript/fetch

出典: フリー教科書『ウィキブックス(Wikibooks)』

fetch() メソッドは、ネットワークリソースを取得するための現代的な API です。このメソッドは Promise ベースであり、XMLHttpRequest に比べてより柔軟でパワフルなリクエスト/レスポンス機能を提供します[1]

構文

[編集]
partial interface mixin WindowOrWorkerGlobalScope {
  [NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
};

パラメータ

[編集]

input

[編集]

リソースを示す Request オブジェクトまたは URL を表す文字列(RequestInfo 型)。

init

[編集]

オプションの RequestInit オブジェクト。リクエストのカスタマイズに使用されます。主なプロパティには以下があります:

  • method: リクエストに使用する HTTP メソッド("GET", "POST" など)
  • headers: HTTP ヘッダーを表すオブジェクト
  • body: リクエストボディ(POST リクエストなどで送信するデータ)
  • mode: リクエストモード("cors", "no-cors", "same-origin" など)
  • credentials: Cookie をリクエストに含めるかどうか("omit", "same-origin", "include")
  • cache: キャッシュモード("default", "no-store", "reload" など)
  • redirect: リダイレクトの処理方法("follow", "error", "manual")
  • referrer: リファラー情報
  • referrerPolicy: リファラーポリシー
  • integrity: サブリソースの完全性値
  • keepalive: ページのアンロード後もリクエストを続行するかどうか
  • signal: リクエストをキャンセルするための AbortSignal

戻り値

[編集]

リクエストの結果を表す Promise<Response> オブジェクト。 Response オブジェクトの主なプロパティとメソッド:

  • status: HTTP ステータスコード(200, 404 など)
  • statusText: ステータスメッセージ("OK", "Not Found" など)
  • ok: ステータスコードが 200-299 の範囲内かどうか
  • headers: レスポンスヘッダー
  • body: レスポンスボディのストリーム
  • text(): レスポンスをテキストとして取得する Promise を返す
  • json(): レスポンスを JSON としてパースする Promise を返す
  • blob(): レスポンスを Blob として取得する Promise を返す
  • formData(): レスポンスを FormData として取得する Promise を返す
  • arrayBuffer(): レスポンスを ArrayBuffer として取得する Promise を返す

[編集]

基本的な使用方法

[編集]

以下のプログラムは、fetch() の基本的な使用方法を示しています。

// GET リクエストを送信
fetch('https://api.example.com/data')
  .then(response => {
    // レスポンスステータスを確認
    if (!response.ok) {
      throw new Error(`HTTP エラー: ${response.status}`);
    }
    return response.json(); // JSON としてパース
  })
  .then(data => {
    console.log('取得したデータ:', data);
  })
  .catch(error => {
    console.error('fetch エラー:', error);
  });

// async/await を使用した書き方
async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    
    if (!response.ok) {
      throw new Error(`HTTP エラー: ${response.status}`);
    }
    
    const data = await response.json();
    console.log('取得したデータ:', data);
  } catch (error) {
    console.error('fetch エラー:', error);
  }
}

fetchData();

このプログラムでは、fetch() を使用して API からデータを取得し、レスポンスを JSON としてパースしています。Promise チェーンと async/await の両方の書き方を示しています。

カスタムリクエストの送信

[編集]

以下のプログラムは、fetch() を使用してカスタマイズされたリクエストを送信する方法を示しています。

// POST リクエストを送信
async function postData(url, data) {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer YOUR_TOKEN'
    },
    body: JSON.stringify(data)
  });
  
  return response.json();
}

// 使用例
const userData = {
  name: '山田太郎',
  email: 'yamada@example.com',
  age: 30
};

postData('https://api.example.com/users', userData)
  .then(responseData => {
    console.log('サーバーレスポンス:', responseData);
  })
  .catch(error => {
    console.error('エラー:', error);
  });

このプログラムでは、fetch()init パラメータを使用して、POST メソッド、カスタムヘッダー、およびリクエストボディを持つカスタムリクエストを送信しています。

ファイルのアップロード

[編集]

以下のプログラムは、fetch() を使用してファイルをアップロードする方法を示しています。

// フォームデータを使用したファイルアップロード
async function uploadFile(file) {
  const formData = new FormData();
  formData.append('file', file);
  formData.append('filename', file.name);
  
  try {
    const response = await fetch('https://api.example.com/upload', {
      method: 'POST',
      body: formData
    });
    
    if (!response.ok) {
      throw new Error(`アップロードエラー: ${response.status}`);
    }
    
    return await response.json();
  } catch (error) {
    console.error('アップロードエラー:', error);
    throw error;
  }
}

// ファイル入力要素からファイルを取得
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', async (event) => {
  const file = event.target.files[0];
  if (file) {
    try {
      const result = await uploadFile(file);
      console.log('アップロード成功:', result);
    } catch (error) {
      console.error('アップロード失敗:', error);
    }
  }
});

このプログラムでは、FormData オブジェクトを使用してファイルをアップロードしています。ファイル入力要素からファイルを取得し、fetch() を使用してサーバーにアップロードしています。

リクエストのキャンセル

[編集]

以下のプログラムは、AbortController を使用して fetch() リクエストをキャンセルする方法を示しています。

// キャンセル可能なフェッチリクエスト
function fetchWithTimeout(url, options = {}, timeoutMs = 5000) {
  const controller = new AbortController();
  const { signal } = controller;
  
  // タイムアウトを設定
  const timeout = setTimeout(() => {
    controller.abort();
  }, timeoutMs);
  
  return fetch(url, { ...options, signal })
    .then(response => {
      clearTimeout(timeout);
      return response;
    })
    .catch(error => {
      clearTimeout(timeout);
      if (error.name === 'AbortError') {
        throw new Error(`リクエストがタイムアウトしました (${timeoutMs}ms)`);
      }
      throw error;
    });
}

// 使用例
fetchWithTimeout('https://api.example.com/data', {}, 3000)
  .then(response => response.json())
  .then(data => console.log('データ:', data))
  .catch(error => console.error('エラー:', error));

// ユーザーアクションでキャンセルする例
const controller = new AbortController();
const { signal } = controller;

const fetchPromise = fetch('https://api.example.com/large-data', { signal })
  .then(response => response.json())
  .then(data => console.log('データ:', data))
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('ユーザーによってリクエストがキャンセルされました');
    } else {
      console.error('エラー:', error);
    }
  });

// キャンセルボタンのイベントリスナー
document.getElementById('cancelButton').addEventListener('click', () => {
  controller.abort();
});

このプログラムでは、AbortControllersignal を使用して fetch() リクエストをキャンセルする方法を示しています。タイムアウトでキャンセルする例とユーザーアクションでキャンセルする例の両方を含んでいます。

様々なデータタイプの処理

[編集]

以下のプログラムは、fetch() を使用して様々なデータタイプを処理する方法を示しています。

// 様々なレスポンスタイプを処理する関数
async function fetchDifferentTypes() {
  // テキストを取得
  const textResponse = await fetch('https://example.com/text');
  const text = await textResponse.text();
  console.log('テキスト:', text);
  
  // JSON を取得
  const jsonResponse = await fetch('https://api.example.com/data');
  const jsonData = await jsonResponse.json();
  console.log('JSON データ:', jsonData);
  
  // Blob を取得(画像など)
  const imageResponse = await fetch('https://example.com/image.jpg');
  const imageBlob = await imageResponse.blob();
  const imageUrl = URL.createObjectURL(imageBlob);
  document.getElementById('image').src = imageUrl;
  
  // ArrayBuffer を取得(バイナリデータ)
  const binaryResponse = await fetch('https://example.com/binary-data');
  const buffer = await binaryResponse.arrayBuffer();
  const dataView = new DataView(buffer);
  console.log('バイナリデータ 最初の4バイト:', dataView.getUint32(0));
}

fetchDifferentTypes().catch(error => {
  console.error('フェッチエラー:', error);
});

このプログラムでは、fetch() を使用して異なるタイプのデータ(テキスト、JSON、Blob、ArrayBuffer)を取得して処理する方法を示しています。

注意点

[編集]
  • クロスオリジンリクエスト: 異なるオリジンへのリクエストは CORS ポリシーに従う必要があります。
  • ステータスコードの処理: fetch() は HTTP エラーレスポンス(404、500 など)を拒否しません。response.ok をチェックする必要があります。
  • Cookie: デフォルトでは、異なるオリジンへのリクエストに Cookie は含まれません。含める場合は credentials: 'include' を指定します。
  • リダイレクト: デフォルトでは、リダイレクトは自動的に処理されます。
  • キャッシュ: デフォルトでは、ブラウザのキャッシュメカニズムが使用されます。
  • ストリーミング: レスポンスボディは一度だけ消費できるストリームです。複数回アクセスする場合は response.clone() を使用します。

脚註

[編集]
  1. ^ この API は、ウェブアプリケーションでのデータ取得や API 通信の標準的な方法となっています。

外部リンク

[編集]

附録

[編集]

以下は、Fetch APIに関連する主要なオブジェクトや概念を「名称」と「解説」の順に表組みにしたものです。

名称 解説
fetch() ネットワークリクエストを送信し、レスポンスを取得するための関数。Promiseを返す。
Request リクエストを表すオブジェクト。URL、メソッド、ヘッダー、ボディなどを含む。
Response リクエストに対するレスポンスを表すオブジェクト。ステータスコード、ヘッダー、ボディなどを含む。
Headers HTTPヘッダーを表すオブジェクト。ヘッダーの追加、取得、削除などの操作が可能。
Body リクエストやレスポンスのボディを表すミックスイン。テキスト、JSON、Blobなどの形式でデータを取得できる。
URLSearchParams URLのクエリパラメータを操作するためのユーティリティクラス。
AbortController リクエストを中止するためのコントローラー。AbortSignalを提供する。
AbortSignal AbortControllerによって生成され、リクエストが中止されたかどうかを示す信号。

これらのオブジェクトや概念は、Fetch APIを使用してネットワークリクエストを扱う際に重要な役割を果たします。