Fetchは、 XMLHttpRequest に関連するすべての手間をかけずに、Ajaxリクエストを実行できる新しいpromiseベースのAPIです。 この投稿でわかるように、Fetchは非常に使いやすく、操作が簡単で、APIからのリソースのフェッチを大幅に簡素化します。 さらに、最近のすべてのブラウザでサポートされるようになったため、Fetchを使用するのは非常に簡単です。

リクエストを取得

GET を実行して、 JSONPlaceholderAPIからのダミーデータを取得して簡単なGETリクエストを示しましょう。

fetch('https://jsonplaceholder.typicode.com/users')
  .then(res => res.json())
  .then(res => res.map(user => user.username))
  .then(userNames => console.log(userNames));

そして、出力は次のようなユーザー名の配列になります。

["Bret", "Antonette", "Samantha", "Karianne", "Kamren", "Leopoldo_Corkery", "Elwyn.Skiles", "Maxime_Nienow", "Delphine", "Moriah.Stanton"]

JSON応答が予想される場合、最初に json()メソッドを呼び出して、Responseオブジェクトを操作可能なオブジェクトに変換する必要があります。 代わりにXML応答が必要な場合は、text()を使用できます。

リクエストの投稿、配置、削除

GET 以外のリクエストを行うには、使用するメソッド、および必要なヘッダーとリクエストの本文を使用して、フェッチ呼び出しの2番目の引数としてオブジェクトを渡します。

const myPost = {
  title: 'A post about true facts',
  body: '42',
  userId: 2
}

const options = {
  method: 'POST',
  body: JSON.stringify(myPost),
  headers: {
    'Content-Type': 'application/json'
  }
};

fetch('https://jsonplaceholder.typicode.com/posts', options)
  .then(res => res.json())
  .then(res => console.log(res));

JSONPlaceholder は、投稿されたデータをIDを付けて送り返します。

Object {
  body: 42,
  id: 101,
  title: "A post about true facts",
  userId: 2
}

リクエストの本文は文字列化する必要があることに注意してください。 フェッチ呼び出しに使用できる他のメソッドは、 DELETE PUT HEAD 、およびOPTIONSです。

エラー処理

Fetch APIでのエラー処理に関しては、落とし穴があります(しゃれを意図しています😉)。リクエストがエンドポイントに適切にヒットして戻ってきた場合、エラーはスローされません。 つまり、エラー処理は、フェッチプロミスチェーンの最後でcatch呼び出しをチェーンするほど単純ではありません。

ただし、幸いなことに、フェッチ呼び出しからの応答オブジェクトには ok プロパティがあり、要求の成功に応じてtrueまたはfalseのいずれかになります。 ok がfalseの場合は、 Promise.reject()を使用できます。

fetch('https://jsonplaceholder.typicode.com/postsZZZ', options)
  .then(res => {
    if (res.ok) {
      return res.json();
    } else {
      return Promise.reject({ status: res.status, statusText: res.statusText });
    }
  })
  .then(res => console.log(res))
  .catch(err => console.log('Error, with message:', err.statusText));

上記の例では、存在しないエンドポイントを呼び出しているため、promiseは拒否されます。 連鎖キャッチコールがヒットし、以下が出力されます。

"Error, with message: Not Found"

フェッチ+非同期/待機

FetchはpromiseベースのAPIであるため、 async 関数を使用することは、コードを推論しやすく、同期的に見えるようにするための優れたオプションです。 たとえば、 async / await 関数は、単純な GET リクエストを実行し、返されたJSON応答からユーザー名を抽出して、結果をコンソールに記録します。

async function fetchUsers(endpoint) {
  const res = await fetch(endpoint);
  let data = await res.json();

  data = data.map(user => user.username);

  console.log(data);
}

fetchUsers('https://jsonplaceholder.typicode.com/users');

または、async / await関数からpromiseを返すだけで、関数を呼び出した後、次に呼び出しをチェーンし続けることができます。

async function fetchUsers(endpoint) {
  const res = await fetch(endpoint);
  const data = await res.json();

  return data;
}

fetchUsers('https://jsonplaceholder.typicode.com/users')
  .then(data => {
    console.log(data.map(user => user.username));
  });

json()を呼び出すと、promiseが返されるため、上記の例では、非同期関数でreturn dataを実行すると、promiseが返されます。

また、応答の ok がfalseの場合もエラーをスローし、promiseチェーンで通常どおりエラーをキャッチできます。

async function fetchUsers(endpoint) {
  const res = await fetch(endpoint);

  if (!res.ok) {
    throw new Error(res.status); // 404
  }

  const data = await res.json();
  return data;
}

fetchUsers('https://jsonplaceholder.typicode.com/usersZZZ')
  .then(data => {
    console.log(data.map(user => user.website));
  })
  .catch(err => console.log('Ooops, error', err.message));
Ooops, error 404

ポリフィル

ブラウザのサポート

フェッチを使用できますか? caniuse.comからの主要なブラウザーでのフェッチ機能のサポートに関するデータ。