当サイトは、アフィリエイト広告を利用しています

javascriptの非同期通信処理~fetchAPI~

作成日:2022月05月20日
更新日:2025年07月26日

javascriptの非同期通信処理のFetch API
について調べたので忘備録として残す。

fetchAPIとは

Fetch APIは、ブラウザのJavaScript環境で提供される
HTTPリクエストを行うためのネイティブなAPI。

Fetch APIは、従来のXMLHttpRequestよりもモダンで
直感的な方法でHTTPリクエストを処理することができる

中身的なことをいうとPromiseを使ってブラウザと WEBサーバ間でデータの送受信を行うことができる。

javascriptで非同期通信を行う方法はfetchAPIを使う他に

  • XMLHttpRequest
  • axios(JavaScriptでHTTPリクエストを行うためのライブラリ)

を使う方法がある
それぞれ下記でまとめています。

基本構文

  • 第一引数はURLやパス
  • 第二引数はオプション

構文

jsx
fetch('URL等',{option}).then(...);

fechの結果はPromiseオブジェクトで返却され、resolveにはResponseオブジェクトが   渡される。

オプションの詳細はFetch の使用参照

レスポンスオブジェクトとは?

fetchAPIの戻り値のresolveに渡されるオブジェクト
通信結果ステータスや取得したdataなどを保持している

プロパティ

  • response.ok
    ok:通信が成功したかどうか

  • response.status
    status:レスポンスのステータスコード  

などをもっている。

メソッド

メソッドとしては

  • text()
  • arraybuffer()
  • blob()
  • json()
  • formData()

をもっておりこれらのメソッドは全てPromiseを返す。 fetchAPIのPromiseが解決されるのはレスポンスヘッダが全部返ってきたときのため
本文部分は別のPromiseで取得することになる。

HTTPのレスポンスは下記の順で返却され、

  1. ステータスコード
  2. ヘッダ ← ここが帰ってきた時にfetchAPIのPromiseが解決される
  3. レスポンスボディ ← json()などのresponseオブジェクトのメソッドで再度、Promiseで取得する

詳しくはResponseを参照

構文部分の実装

jsonplaceholderからのデータ取得をfechAPIを実装してみる

通常パターン

js
const fech = () =>
fetch("https://jsonplaceholder.typicode.com/todos/1", {
method: "GET"
})
.then((response) => {
if (response.ok) {
// jsonに変換する
// Promiseで返却される
return response.json();
} else {
// reject
throw new Error(response.status);
}
})
// response.json()のresolve
.then((res) => {
// jsonに変換したresをログ表示
console.log(JSON.stringify(res, null, 3));
})
// rejectの結果を処理
.catch((status) => console.log(status));
fech();
// 実行結果
// {
// "userId": 1,
// "id": 1,
// "title": "delectus aut autem",
// "completed": false
// }
  • オプションでGETを指定
  • responseオブジェクトをjsonに変換して取得
  • response.okがfalseの場合は通信失敗。
  • 失敗した場合はステータスをログに出力

try...catch + awaitパターン

fetchをasync、awaitと組み合わせて使うことで下記のような利点がある

  • 同期処理のように書ける

    • 処理の流れが上から下へ直感的に読める。
  • 可読性が高い

    • .then()チェーンよりもスッキリして読みやすい。
    • ネストが浅くなる。
  • エラーハンドリングを一箇所でできる

    • 複数の awaittry...catch でまとめて安全に処理できる。
    • fetch の失敗も、response.json() の失敗もまとめて対応できる。
index.js
// 非同期関数として定義(fetchをawaitで使うため)
const fechFunc = async () => {
// 送信するデータ(JSON形式)
const sendData = {
title: "a1 test",
body: "this is test by a1",
userId: 1,
};
// fetchによる非同期通信(POSTリクエスト)
// エラー処理は try-catch で行う
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST", // HTTPメソッド:POST(データ送信)
headers: {
"Content-Type": "application/json", // 送信データの形式を指定
},
body: JSON.stringify(sendData), // JavaScriptオブジェクトをJSON文字列に変換して送信
});
// レスポンスのステータスコードが成功(200台)以外の場合はエラーとして処理
if (!response.ok) {
throw new Error(response.status); // エラーステータスを例外として投げる
}
// レスポンスのJSONデータを取得(非同期処理)
const data = await response.json();
// 結果を整形してコンソールに出力(インデント3)
console.log(JSON.stringify(data, null, 3));
} catch (error) {
// エラーが発生した場合にここで処理される
console.log("Error:", error.message);
}
};
// 非同期関数を実行
fechFunc();
// 実行結果
// {
// "title": "a1 test",
// "body": "this is test by a1",
// "userId": 1,
// "id": 101
// }

参考

fetchAPIのサンプル実装

reactでサンプル実装してみる

POSTの場合(useStateを使う)

fetchAPIを使い、jsonplaceholderにPOSTでデータを登録し
登録したデータを取得、画面に表示する

App.js
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
import React, { useState } from 'react';
export default function App() {
const [post, setPosts] = useState([]);
// POSTの登録処理
const registData = async () => {
// 送るデータ
const sendData = [
{
title: 'a1 test',
body: 'this is test by a1',
userId: 1,
},
{
title: 'a2 test',
body: 'this is test by a2',
userId: 2,
},
];
try {
// fetchで非同期通信処理
const res = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
// サーバに対してヘッダーで解析方法を指定する
headers: {
'Content-Type': 'application/json',
},
// 送るデータ
body: JSON.stringify(sendData),
});
if (!res.ok) {
throw new Error(response.status);
}
// レスポンスのJSONデータを取得(非同期処理)
const data = await res.json();
// オブジェクトを表示用にListに変換
if ('object' === typeof data) {
//stateを更新
setPosts(() =>
Object.values(data).filter((prop) => typeof prop === 'object')
);
}
} catch (status) {
console.log(status);
}
};
return (
<div>
<h2>データ</h2>
<button type="button" onClick={() => registData()}>
データ取得
</button>
<div>
{post &&
post.map(({ userId, id, title }) => (
<div css={Container} key={title}>
<div css={item}>{userId}</div>
<div css={item}>{title}</div>
</div>
))}
</div>
</div>
);
}
const Container = () => [
css`
display: flex;
justify-content: flex-start;
`,
];
const item = () => [
css`
text-align: center;
width: 100%;
border: 1px solid black;
`,
];
  • async,awaitを使って処理を制御する。
    ※しないとレンダリングでエラーになる

POST画面動作イメージ

react fetchAPI(Post)

GETの場合(useState、useRef,useEffectを使う)

fetchAPIを使い、jsonplaceholderにPOSTでデータを取得し、
画面の検索条件で絞り込む

App.js
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
import React, { useEffect, useRef, useState } from 'react';
export default function App() {
// 取得データstate
const [post, setPosts] = useState([]);
// 検索条件
const [query, setQuery] = useState();
const queryRef = useRef(null);
// 検索処理
const search = () => {
// useRefの値でqueryのstateを更新
if (queryRef.current.value) {
setQuery(() => Number(queryRef.current.value));
}
};
useEffect(() => {
//queryのstateが更新された場合にデータ取得
registData(query);
}, [query]);
// データ取得処理
const registData = async (query) => {
try {
const response = await fetch(
'https://jsonplaceholder.typicode.com/posts',
{
method: 'GET',
}
);
if (!response.ok) {
throw new Error(response.status);
}
const data = await response.json();
// 画面表示データをqueryで絞り込んだデータで更新
setPosts(() => data.filter((record) => record.userId === query));
} catch (error) {
console.error('データ取得に失敗しました:', error);
}
};
return (
<div>
<h2>データ</h2>
<input ref={queryRef} placeholder="Please input Number Only" />
<button type="button" onClick={() => search()}>
検索
</button>
<div>
{post &&
post.map(({ userId, id, title }) => (
<div css={Container} key={title}>
<div css={item}>{userId}</div>
<div css={item}>{title}</div>
</div>
))}
</div>
</div>
);
}
const Container = () => [
css`
display: flex;
justify-content: flex-start;
`,
];
const item = () => [
css`
text-align: center;
width: 100%;
border: 1px solid black;
`,
];

処理概要

  • useEffectでstate(query)変更時にデータの再取得をするようにする
  • 検索条件をuseRefで紐づけ値を取得できるようにする
  • 検索押下で検索条件の値でstate(query)を更新
  • useEffectでデータ取得実施
  • データ取得メソッドで検索条件での絞り込み実施

GET画面動作イメージ

react fetchAPI

注意

IEでは使えない

FetchAPIはモダンブラウザの標準機能のためライブラリのインストールなどは不要だが
使えないブラウザもあるため注意が必要

Fetchから返されるPromiseは404や500をrejectしない

FetchAPIはサーバーからヘッダーまで帰ってきた時点で成功となるため
ステータスコードの404や500が帰ってきたとしてもエラーにならないため
responseオブジェクトのokプロパティで対応する必要がある

参考

関連記事

新着記事

タグ別一覧
top