JavaScript

最終更新日:
公開日:

レシピ

Ajax

Fetch APIを使ってAjaxを実装する

Fetch APIを使ったAjaxによるファイルの読み込み、各種メソッドを使ったデータ送信を実装する方法について解説します。

この記事のポイント

  • Fetch APIはjQueryのajaxメソッドのようにシンプルな手順でAjaxを実装できる
  • RESTful APIで使う4種類のメソッドGETPOSTPUTDELETEに対応したAjaxを実装する

目次

Fetch APIを使ったAjax

JavaScriptではサーバーサイドとの非同期通信を行う「Ajax」を実装する方法として、大きく次の3種類の方法があります。

  • Fetch API
  • XMLHttpRequestオブジェクト
  • jQueryのajaxメソッド

2つ目のXMLHttpRequestオブジェクトはやや手順が多いため、少し前まではjQueryを使った方法が多く使われていました。
しかし最近は各種ブラウザが対応したことと、手順が簡易的な1つ目のFetch APIを使ったAjax実装をする機会が増えてきています。
今回はそのFetch APIの基本的な使い方を解説していきます。

なお、XMLHttpRequestオブジェクトを使ったAjaxの実装については別記事「XMLHttpRequestオブジェクトを使ってAjaxを実装する」をご覧ください。

GETメソッドによるデータの取得

GETメソッドを使った通信はデータを取得するときによく使用されます。
以下の例はサーバーからJSON形式のデータが入ったファイル「test.json」を取得してコンソールに出力します。

取得するファイル test.json

[
	{
		"title": "K331",
		"category": "Classic",
		"release_date": "2019-11-25"
	},
	{
		"title": "Paradise",
		"category": "Rock",
		"release_date": "2019-12-18"
	},
	{
		"title": "Baby",
		"category": "Pops",
		"release_date": "2020-01-07"
	}
]

こちらのファイルを、以下のコードで取得します。

JS コード例(1)

window.addEventListener('DOMContentLoaded', () => {

	fetch('/text/test.json') // (1) 読み込み
	.then(response => response.json()) // (2) レスポンスデータの受け取り
	.then(data => { // (3) データの処理
		console.log(data);
	});

});

Fetch APIは使用する前にオブジェクトなどは作成せずに使用することができます。

(1)ではファイルのURL「‘/text/test.json’」を指定してfetchメソッドを実行し、通信を開始します。
続いて、2つのthenメソッドを使ってレスポンスを処理していきます。
この仕組みを「メソッドチェーン」と呼び、fetchメソッドに続いて前から順に実行されていきます。

1つ目のthenメソッドではレスポンスデータが入ったResponseオブジェクトを受け取って処理を実行します。
今回の例では受け取る変数をresponseにしていますが、変数名はなんでも大丈夫です。

(2)ではResponseオブジェクトjsonメソッドを実行して、レスポンスからJSONデータを取得します。

続いて2つ目のthenメソッドに移ります。
ここでは、受け取ったJSONデータをコンソール出力します。

取得したデータを出力すると以下のようになります。

コンソール出力例

(3) [{…}, {…}, {…}]
	0: {title: "K331", category: "Classic", release_date: "2019-11-25"}
	1: {title: "Paradise", category: "Rock", release_date: "2019-12-18"}
	2: {title: "Baby", category: "Pops", release_date: "2020-01-07"}

続いて、より実用的な使い方としてファイルの読み込みが成功したかを確認する方法について解説します。

Ajaxの通信が成功したか確認する

Ajaxでは通信状況が悪かったり、サーバーに存在しないファイルを参照したときなど読み込みに失敗してしまうことがあります。
通信が成功したかどうかは、Responseオブジェクトokプロパティを参照して調べることができます。
okプロパティは論理値(Boolean)で通信が成功したらtrue、失敗したらfalseが入ります。

JS コード例(2)

window.addEventListener('DOMContentLoaded', () => {

	fetch('/text/test2.json')
	.then(response => {

		// (1) 通信が成功したか確認する
		if (!response.ok) {

			// (2) 通信に失敗したときはエラーを発生させる
			throw new Error('Not ok');
		}
		// (3) レスポンスデータからJSONデータを取得
		return response.json();
	})
	.then(data => {
		// (4) 受け取ったデータをコンソール出力
		console.log(data);
	})
	.catch(error => {
		// (5) エラーを受け取ったらコンソール出力
		console.error(error);
	});

});

こちらの例ではif文okプロパティの値をチェックします。
もし値がfalseの場合は、(2)で明示的にエラーを発生させます。
エラーメッセージはここでは「Not ok」としていますが、自由に指定することができます。

通信が成功したときは(3)でレスポンスからJSONデータを取得して、returnを使って続くthenメソッドにデータを渡します。
冒頭のコード例(2)では「return」は省略していましたが、同じことをしてデータの受け渡しをしていました。

無事にデータを受け取ったら(4)でコンソール出力して、一通りの処理は終了します。

しかし、もし通信に失敗していたときは(2)でエラーを発生させています。
ここで発生したエラーはthenメソッドの後にあるcatchメソッドで受け取ることができます。
今回はコンソールにエラー内容を出力して終了します。
もしファイルが見つからなったときは以下のようなエラー内容が出力されます。

コンソール出力例

Error: Not ok
	at index.html:25

エラー内容のうち、1行目は(2)で指定したメッセージが出力され、2行目はファイル名とエラー箇所が出力されます。

GETメソッドによるデータの送信

検索やページング(ページネーション)など、公開しているデータにアクセスするときはGETメソッドを使ってデータを送信することがあります。
GETメソッドによるデータ送信はURLにパラメータを指定するのと同じ形です。

以下の例では、a要素をクリックしたらhref属性のURLと一緒にパラメータ「mode」「id」をデータとして一緒に送信します。

HTML コード例

<a id="link_next" href="/page.php?mode=next&id=5">次のページへ</a>

JS コード例

window.addEventListener('DOMContentLoaded', () => {

	// (1) id属性からa要素を取得
	const a_element = document.getElementById("link_next");

	// (2) イベントリスナー「クリック」を設定
	a_element.addEventListener('click', (e)=> {

		// (3) デフォルトの挙動(リンクによるページ移動)を解除
		e.preventDefault();

		// (4) Fetch APIでデータ送信
		fetch( a_element.href, {
			method: 'GET'
		})
		.then(response => response.json())
		.then(data => {
			console.log(data);
		})
		.catch((error) => {
			console.error(error);
		});
	});
});

今回はa要素のイベントリスナーの登録などが加わりますが、Fetch APIの実行の流れは先述したコードと同じです。
a要素がクリックされると、href属性をそのままFetch APIの送信先として指定し、パラメータも一緒に送信します。

通信が成功すると受け取ったレスポンスからJSONデータを取得して、コンソールに出力します。
もし通信に失敗したときはcatch()が実行されて、エラー内容をコンソールに出力します。

赤字の箇所は肝となる部分で、URLの指定ではa要素href属性をそのまま指定する「a_element.href」を記述しています。

もう1つの「method: ‘GET’」は通信メソッドの指定です。
今回はGETメソッドなので「GET」としていますが、フォームの入力値やファイルなどを送信するときは「POST」や「PUT」を指定することができます。

POSTメソッドによるデータの送信

POSTメソッドはフォームに入力された値をサーバーに送信するときに使用されます。
RESTfulでは新規で会員登録を行うときのような「データの新規登録」のシーンでAPIと通信を行うときに使用されます。

今回は簡易的な新規会員登録フォームを想定して、「ユーザー名(input_username)」と「パスワード(input_password)」に入力された値を送信ボタンが押されたタイミングでサーバーに送信します。
今回は使用例なので、最初からvalue属性に値を指定しておき、すでに入力があるものとして進めていきます。

HTML コード例

<article>
	<h1>新規会員登録</h1>
	<form method="post" action="">
		<div>
			<label for="input_name">ユーザー名</label>
			<input type="text" name="input_username" value="Hanako">
		</div>
		<div>
			<label for="input_password">パスワード</label>
			<input type="password" name="input_password" value="Password">
		</div>
		<input type="submit" id="btn_submit" name="btn_submit" value="送信">
	</form>
</article>

以下のJavaScriptコードでは、input要素value属性から入力値を取得してFormDataオブジェクトにセットします。
その後、XMLHttpRequestオブジェクトsendメソッドでリクエストを送信するときにFormDataオブジェクトも一緒に送信することで、フォームのデータをサーバーに送信します。

JS コード例

window.addEventListener('DOMContentLoaded', () => {

	// (1) 送信ボタンの取得
	const btn_submit = document.getElementById("btn_submit");
	const fd = new FormData();

	btn_submit.addEventListener('click', (e)=> {
		e.preventDefault();

		// (2) フォーム入力欄のHTMLを取得
		const input_username = document.querySelector('input[name=input_username]');
		const input_password = document.querySelector('input[name=input_password]');

		// (3) FormDataオブジェクトに入力値をセット
		fd.append('username', input_username.value);
		fd.append('password', input_password.value);

		// (4) POSTメソッドでデータを送信
		fetch( 'regist.php', {
			method: 'POST',
			body: fd
		})
		.then(response => response.json())
		.then(data => {
			console.log(data);
		})
		.catch((error) => {
			console.error(error);
		});
	});
});

(1)はid属性から送信ボタンのHTMLを取得して、その後にフォームデータを取得するためのFormDataオブジェクトの初期化(コンストラクタ)を実行します。

その後、送信ボタンがクリックされたときに送信処理が実行されるようにイベントリスナーの登録を行います。
(2)ではフォームから「ユーザー名」「パスワード」の入力欄になるinput要素を取得します。

(3)は先ほど取得した2つのinput要素から入力値を取得して、FormDataオブジェクトにセットしています。
入力値はvalue属性を参照すると取得できます。

(4)でいよいよFetch APIによるデータの送信を行います。
fetchメソッドの第1パラメータには送信先のURL、第2パラメータには送信内容を指定します。

今回は送信先に「regist.php」を指定し、「method」にはPOST、そして送信データとなる「body」にはFormDataオブジェクトをそれぞれ指定して、Ajax通信を実行します。

レスポンスデータを受け取った後については、先述したGETメソッドによるデータ送信と同様です。
受け取ったデータをthenメソッド内で処理することができます。

PUTメソッドによるデータの送信

PUTメソッドはPOSTメソッドと同様に、フォームに入力された値をサーバーに送信するときに使用します。
RESTfulではすでに登録されたデータを更新するためにAPIと接続するときに使用されます。
上記のPOSTメソッドが会員の新規登録のようなシーンで使われるのに対して、PUTメソッドは登録情報の更新(編集)のようなシーンで使うイメージです。

以下の例はすでに登録された会員のパスワード変更を想定して、「パスワード(input_password)」の入力蘭と更新するデータを特定するための「ユーザーID(input_userid)」を送信ボタンが押されたタイミングでサーバーに送信します。

今回は使用例なのでパスワードはすでに「NewPassword」と入力されていることとして進めていきます。
また、ユーザーIDはinput要素の「type=”hidden”」として設置します。

HTML コード例

<article>
  <h1>登録情報の更新</h1>
	<form method="post" action="">
		<div>
			<label for="input_password">パスワード</label>
			<input type="password" name="input_password" value="NewPassword">
		</div>
		<input type="submit" id="btn_submit" name="btn_submit" value="送信">
		<input type="hidden" name="input_userid" value="1102">
	</form>
</article>

以下のJavaScriptコードでは、input要素value属性から入力値を取得してFormDataオブジェクトにセットします。
その後、XMLHttpRequestオブジェクトsendメソッドでリクエストを送信するときにFormDataオブジェクトも一緒に送信することで、フォームのデータをサーバーに送信します。

JS コード例

window.addEventListener('DOMContentLoaded', () => {

	// (1) 送信ボタンの取得
	const btn_submit = document.getElementById("btn_submit");
	const fd = new FormData();

	btn_submit.addEventListener('click', (e)=> {
		e.preventDefault();

		// (2) フォーム入力欄のHTMLを取得
		const input_password = document.querySelector('input[name=input_password]');
		const input_userid = document.querySelector('input[name=input_userid]');

		// (3) FormDataオブジェクトに入力値をセット
		fd.append('password', input_password.value);
		fd.append('userid', input_userid.value);

		// (4) PUTメソッドでデータを送信
		fetch( 'edit.php', {
			method: 'PUT',
			body: fd
		})
		.then(response => response.json())
		.then(data => {
			console.log(data);
		})
		.catch((error) => {
			console.error(error);
		});
	});
});

大まかな流れは上記PUTメソッドと同様です。

(4)で通信メソッドを「PUT」と指定している点がポイントです。
それ以外は入力項目が「ユーザー名」から「ユーザーID」に置き換わっていたり、送信先のURLが「edit.php」となっている意外はほぼ同じです。

DELETEメソッドによるデータの送信

DELETEメソッドはPOSTメソッドやPUTメソッドと同様にサーバーへデータを送信するときに使います。
使用するシーンは登録されたデータを削除するときにAPIと通信するときです。
上記のPUTメソッドが会員情報の更新(編集)だったのに対して、DELETEメソッドは退会時などの削除を実行するシーンで使うイメージです。

以下の例はすでに登録された会員のデータを削除することを想定して、削除するデータを特定するための「ユーザーID(input_userid)」を送信ボタンが押されたタイミングでサーバーに送信します。

HTML コード例

<article>
	<h1>退会</h1>
	<p>このまま退会を進める場合は「退会する」ボタンを押してください。</p>
	<form method="post" action="">
		<input type="submit" id="btn_submit" name="btn_submit" value="退会する">
		<input type="hidden" name="input_userid" value="1102">
	</form>
</article>

以下のJavaScriptコードでは、input要素value属性から入力値を取得してFormDataオブジェクトにセットします。
その後、XMLHttpRequestオブジェクトsendメソッドでリクエストを送信するときにFormDataオブジェクトも一緒に送信することで、フォームのデータをサーバーに送信します。

JS コード例

window.addEventListener('DOMContentLoaded', () => {

	// (1) XMLHttpRequestオブジェクトとFormDataオブジェクトのコンストラクタを実行
	const btn_submit = document.getElementById("btn_submit");
	const fd = new FormData();

	btn_submit.addEventListener('click', (e)=> {
		e.preventDefault();

		// (2) フォーム入力欄のHTMLを取得
		const input_userid = document.querySelector('input[name=input_userid]');

		// (3) FormDataオブジェクトに入力値をセット
		fd.append('userid', input_userid.value);

		// (4) DELETEメソッドでデータを送信
		fetch( 'delete.php', {
			method: 'DELETE',
			body: fd
		})
		.then(response => response.json())
		.then(data => {
			console.log(data);
		})
		.catch((error) => {
			console.error(error);
		});
	});
});

大まかな流れは上記PUTメソッドと同様です。
(4)で通信メソッドに「DELETE」を指定している点が重要なポイントになります。

以上、Fetch APIを使った各種メソッドのAjax実装についてでした。

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

コメントありがとうございます!
運営の参考にさせていただきます。