従来の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は問題なく利用できます。ぜひ活用してください。

Fetch API - Web API | MDN