従来のJavaScriptでは、XMLHttpRequest APIを使って外部サーバーにあるリソースへアクセスしていました。
現在では、fetch APIを利用するのが一般的になっています。
今回は、このfetch APIの使い方を解説します。使い方を習得すれば、外部サーバーとの連携が容易になるでしょう。
イベント呼出しのXMLHttpRequeset API
まずはじめに、従来の XMLHttpRequeset API がどのような形式で利用されていたのか解説します。
XMLHttpRequest APIは、イベントの呼び出しベースでネットワークアクセスをコントロールしていました。
つまり addEventListener
を使って、通信の成否によって呼ばれる関数が変わります。
以下はその例です。
一番下にある xhr.send
でデータ送信を行った後、通信が成功した場合は、 xhr.addEventListener('load')
が実行されます。
通信がエラーとなった場合は、xhr.addEventListener('error')
が呼ばれます。
コードを読むときに、下のデータ送信から上に読み進むため、今どの部分のコードが実行されているのか分かりづらいのが難点です。
// XMLHttpRequestオブジェクトの作成
const xhr = new XMLHttpRequest();
// 通信成功時のイベント
xhr.addEventListener('load', function () {
var data = JSON.parse(xhr.response);
console.log(data);
});
// 通信エラー時のイベント
xhr.addEventListener('error', function () {
console.error(xhr.response);
});
// URLの指定
xhr.open('GET', 'https://example.com/api.json');
// ヘッダーの追加
xhr.setRequestHeader('Content-Type', 'application/json charset=utf-8');
// データ送信
xhr.send();
Promiseベースのfetch API
fetch APIはイベント呼び出しではなく、Promiseベースで処理できるようになりました。
下記のように、コードは先程のXMLHttpRequestに比べて読みやすくなっています。
fetch('https://example.com/api.json', {
headers: {
'Content-Type': 'application/json charset=utf-8'
}
})
.then(res => {
// 通信成功時
})
.catch(err => {
// 通信失敗時
});
さらに、async/awaitを使えばthen/catchのように処理が、括弧内に入らずに済みます。
try {
const res = await fetch('https://example.com/api.json', {
headers: {
'Content-Type': 'application/json charset=utf-8'
}
});
// 通信成功時
} catch (err) {
// 通信失敗時
}
この点においてXMLHttpRequest APIよりfetch APIの方が書きやすい、分かりやすいコードが書けるのが分かってもらえるでしょう。
fetch APIの基本
fetch APIは、 fetch
という関数名で呼び出します。実行時には、2つの引数を指定します。
fetch(url, options);
1つ目の引数 url
はリクエストするURLです。
2つ目の引数 options
は様々な情報が指定できます。
オプションで指定できる情報
fetch APIのオプションは次の通りです。
名前 | 意味 | 指定できる値 |
---|---|---|
method | HTTPメソッドを指定します。省略時はGETになります。 | GET/POST/PUT/PATCH/DELETEなど |
headers | HTTPヘッダーを指定します。Headers またはオブジェクトで指定します。 |
|
body | POSTやPATCHなどで指定するリクエストボディです。 | Blob、BufferSource、FormData、ReadableStreamなど |
mode | CORSに関連するリクエストモードを指定します。 | cors、no-cors、same-origin |
credentials | 認証情報に関する指定をします。 | omit、 same-origin、 includeなど |
cache | キャッシュモードを指定します。 | no-store、reload、no-cache、force-cacheなど |
redirect | リダイレクトが返ってきた時に追従するかどうか指定します。デフォルトはfollowです。 | follow または manual |
referrer | リファラー文字列を指定します。ただし実行元のドメイン、 about:client または空文字に限定されます。 |
|
referrerPolicy | リファラーポリシーを指定します。 | no-referrerなど |
integrity | サブリソース完全性を指定します。意図しない改ざんされたリソース読み込みを防止します。 | |
keepalive | リクエストを長生きさせるかどうか指定します。 | true または false |
signal | リクエストを中断するAbortControllerのインスタンスを渡します。 |
レスポンスの処理
fetch APIの処理結果はResponseオブジェクトで返ってきます。
たとえば、APIにリクエストしてその結果(JSON)を取得したい場合があるかと思います。
そのために json
メソッドが用意されています。
res.json();
しかし、この json
メソッドはPromiseが返却されますので注意してください。つまり次のようになります。
res.json()
.then(json => {
// 処理を記述
});
この場合もasync/awaitを使うとシンプルに書けます。
const json = await res.json();
レスポンスの受け取り方はいくつかありますが、基本的に以下を覚えておけば良いでしょう。
- JSON
res.json() - バイナリデータ(画像など)
res.blob() - テキスト
res.text() - それ以外
res.body()
レスポンスが正しいかどうか
fetch APIでリクエストを送信した後のレスポンスが、正常かどうかの判定は、 try-catchでは判定できないので注意です。
たとえば、400番台のHTTPエラーは catch には流れません。
もし、それらを判定する場合には ok
メソッドを利用してください。
try {
const res = await fetch(url, options);
if (res.ok) {
// リクエストが正しい(200番台)の場合
} else {
// リクエストが正しくない場合
}
} catch (e) {
// それ以外のネットワークエラーなど
}
良くある使い方
ここからfetch APIの良くある使い方を紹介します。
GETリクエストでデータを取得する
外部サーバーからJSONを受け取る場合です。
const res = await fetch(url, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
});
const json = await res.json();
DELETE
メソッドも同じように使います。
const res = await fetch(url, {
method: 'DELETE',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
});
const json = await res.json();
POST/PUT/PATCHでデータを送信する
外部サーバーへPOSTリクエスト(またはPUT/PATCH)を行う場合です。
const res = await fetch(url, {
method: 'POST', // またはPUTやPATCH
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Monaca',
}),
});
const json = await res.json();
POST/PUT/PATCHでファイルをアップロードする
ファイルアップロードする場合には、 FormData
を使います。また、 Content-Type
は指定不要です。
const body = new FormData;
body.append('name', 'Monaca');
body.append('file', file);
const res = await fetch(url, {
method: 'POST', // またはPUTやPATCH
body,
});
まとめ
fetch APIはシンプルなインタフェースで、すぐに理解できるでしょう。
古いWebブラウザでは対応していないものもありますが、Monacaアプリの場合はスマートフォンやタブレット向けに限定されますので、fetch APIは問題なく利用できます。ぜひ活用してください。