はじめに
昔はブラウザ間の互換性に問題があったため、互換性を解決してくれるjQueryがはやりました。
が時代がたつとブラウザ間の互換性は解決され、dom操作も簡単にできるようになりました。
またフレームワーク(Angular,Vue.js,React)が登場しバージョン間の問題もあり新規でjQueryを導入するメリットがなくなってきました。
そのため脱JQueryに向け、よく使用されていると思われるAJAX通信をjavascriptのFetch APIに置き換えるための基本的な使い方をメモとして残します。
単純な例
jsonを返す単純なphpを用意
<?php
// テスト用
sleep(3);
?>
{"foundation": "Mozilla", "model": "box", "week": 45, "transport": "car", "month": 7}
fetchを使用して呼び出し
ajax_test();
function ajax_test() {
fetch("./json_test.php")
.then(response => {
return response.json();
})
.then(json => {
console.log(json);
});
}
thenをチェーンメソッドでつなげ
最初のthenでjsonを受け取りデコード
jsonの結果を次のthenでコンソールに出力
async、awaitを使用した例
単純な例では非同期で行っていたが、async、awaitを使用することにより
プロミスを返す関数の処理を待機させ直列で動作(同期っぽく)させることができる。
async_ajax_test();
async function async_ajax_test() {
const response = await fetch("./json_test.php");
const json = await response.json();
console.log(json);
}
関数にasyncを付けfetchをするときにawaitをして処理を待機させる。
詳しい事は下記が参考になります。
https://qiita.com/jun1s/items/ecf6965398e00b246249
上記だけだとわかりづらいので例
最初に用意したjsonを返す単純なphpをsleepしないバージョン
{"foundation": "Mozilla", "model": "box", "week": 45, "transport": "car", "month": 7}
非同期で呼び出し
ajax_test();
ajax_test2();
function ajax_test() {
fetch("./json_test.php")
.then(response => {
console.log(1);
return response.json();
})
.then(json => {
console.log(2);
});
}
function ajax_test2() {
fetch("./json_test2.php")
.then(response => {
console.log(3);
return response.json();
})
.then(json => {
console.log(4);
});
}
コンソールの結果
3
4
1
2
sleepが入っているjson_test.phpの結果が後から帰ってくるため順番が逆になっている
async、awaitを使用した呼び出し
async_ajax_test();
async function async_ajax_test(){
const response = await fetch("./json_test.php");
console.log(1);
const json = await response.json();
console.log(2);
console.log(3);
const response2 = await fetch("./json_test2.php");
const json2 = await response2.json();
console.log(4);
}
コンソールの結果
1
2
3
4
json_test.phpにsleepが入っているが、json_test.phpの結果をawaitにより待っているため
実行順序通りになっている
エラー処理
非同期時
ajax_test();
function ajax_test() {
fetch("./json_test.php")
.then(response => {
if (!response.ok) {
// httpステータス200以外でも入ってくるので200以外ならばエラーを投げる
console.error(`status = ${response.status}, error = ${response.statusText}`);
throw new Error(response.statusText);
}
return response.json();
})
.then(json => {
console.log(json);
}).catch(error => {
// ネットワーク通信に失敗したとき
console.error(error);
});
}
httpステータス200以外でもthenに入ってくるのでresponse.okで判定し、ネットワークエラー時はcatchで拾う
async、awaitを使用した時
async_ajax_test();
async function async_ajax_test() {
try {
const response = await fetch("./json_test.php");
const json = await response.json();
console.log(json);
} catch (err) {
console.error(err);
}
}
await使用時はtry catchで囲む
ajax通信を途中で中止したい場合
AbortControllerを使用する
<button id="abort_fetch">中断</button>
中断ボタンを用意する
const controller = new AbortController();
const signal = controller.signal;
ajax_test();
function ajax_test() {
fetch("./json_test.php", {signal: signal})
.then(response => {
if (!response.ok) {
// httpステータス200以外でも入ってくるので200以外ならばエラーを投げる
console.error(`status = ${response.status}, error = ${response.statusText}`);
}
return response.json();
})
.then(json => {
console.log(json);
}).catch(error => {
if (error.name === 'AbortError') {
console.log('中断しました。');
return
}
// ネットワーク通信に失敗したとき
console.error(error.message);
});
}
let abort_fetch = document.getElementById('abort_fetch');
abort_fetch.addEventListener('click', function() {
controller.abort();
});
コンソールの結果
中断しました。
非同期処理を中断できるAbortControllerのシグナルオブジェクトを生成し、
fetchの第2引数にsignalオプションを指定します。
イベントリスナーでabort()を呼び出すことでフェッチを中断することができます。
詳しい解説は下記を参考に
https://developer.mozilla.org/ja/docs/Web/API/AbortController/signal
リクエスト時のオプション
fetch apiのデフォルトのメソッドはGETだがPOSTで送信したいときは
fecthの第2引数にオプションを指定する。
<?php
var_dump($_POST);
?>
ajax_test();
function ajax_test() {
let form = new FormData()
form.append('nama', 'test')
fetch("./post_test.php",
{
method: "POST",
body: form
}
).then(response => {
return response.text();
})
.then(test => {
console.log(test);
});
}
コンソールの結果
array(1) {
["nama"]=>
string(4) "test"
}
fetchメソッドの第2引数のオプションにmethodに"POST"を指定してbodyにFormDataオブジェクトを指定する
その他のオプションに関しては下記にて
https://developer.mozilla.org/ja/docs/Web/API/fetch
まとめ
脱JQueryに向け、よく使用されるであろうajaxをFetchApiで実装する例を羅列してみました。
今回紹介したのは基本的な使い方のみでしたが、移行するきっかけになれば幸いです。
Fetchはまだまだ色々な機能がありますのでぜひとも使いこなしてください。