カテゴリー
SugiBlog Webエンジニアのためのお役立ちTips

非同期通信 XMLHttpRequestからFetch APIへ

この記事は最終更新日から1年以上経過しています。

これまで非同期通信といえばXMLHttpRequestでしたが、最近は新たにFetch APIが主流になりつつあるようです。
Fetch APIがいつ定義されたのかは定かではありませんが、HTML Living Standardになった頃でしょうか。
それはともかくFetch APIの使い方を見ていきたいと思います。

まずはこれまでのXMLHttpRequestを確認してみましょう。

XMLHttpRequest

XMLHttpRequestオブジェクトの宣言

let xmlHttp;

if(window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlHttp = new XMLHttpRequest();
} else {
    // code for IE6, IE5
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}

GETの場合

xmlHttp.open("GET", url, true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
xmlHttp.onreadystatechange = function()
{
    if(xmlHttp.readyState == XMLHttpRequest.DONE && xmlHttp.status == 200) {

        const data = xmlHttp.responseText;

        // 何らかの処理

    }
}
xmlHttp.send(null);

POSTの場合

xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
xmlHttp.onreadystatechange = function()
{
    if(xmlHttp.readyState == XMLHttpRequest.DONE && xmlHttp.status == 200) {

        const data = xmlHttp.responseText;

        // 何らかの処理

    }
}
xmlHttp.send(param);

Fetch API

Fetch APIの書式は次のようになります。

let promise = fetch(url, [options])

fetchはPromiseオブジェクトを返してくれます。

以下の例では基本的にPOSTでの通信としています。

fetchを使った非同期処理① [ES2015(ES6)]

まずはPromiseチェーンを使って書いてみます。

const fetchPost = (url, param = "") => {

    fetch(url, {
        method: "POST",
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        },
        body: param
    })
    .then((response) => {
        if(!response.ok) {
            throw new Error(`Error: ${response.status} ${response.statusText}`);
        }
        return response.text();
    })
    .then((data) => {

        // 何らかの処理

    })
    .catch((error) => {
        alert(error);
    });
}

thenが2つに分かれている理由…
response.text()メソッドや後述するresponse.json()メソッド等は非同期のため、2つに分けています。
すぐに処理しようとするとデータが無くてエラーになります。

また、response.text()及びresponse.json()は一度しかレスポンスを得られません。
response.text()を実行した後にresponse.json()を実行すると処理は失敗します。

response.okはHTTPステータスコードが200~299だとtrueを返します。

fetchを使った非同期処理② [ES2017(ES8)]

今度はasync / awaitを使って書いてみましょう。

const fetchPost = async (url, param = "") => {

    const response = await fetch(url, {
        method: "POST",
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        },
        body: param
    });

    if(response.ok) {

        const data = await response.text();

        // 何らかの処理

    } else {

        alert(`Error: ${response.status} ${response.statusText}`);

    }
}

Promiseチェーンを使ったときよりも更にスッキリしましたね。

fetchを使った非同期通信③ JSONデータ [ES2017(ES8)]

今度はJSONデータを受け渡しするパターンです。

const fetchPostJson = async (url, param = {}) => {

    const response = await fetch(url, {
        method: "POST",
        headers: {
            'Content-Type': 'application/json; charset=UTF-8'
        },
        body: JSON.stringify(param)
    });

    if(response.ok) {

        const data = await response.json();

        // 何らかの処理

    } else {

        alert(`Error: ${response.status} ${response.statusText}`);

    }
}

fetchを使った非同期処理④【GETの場合】 [ES2017(ES8)]

GETの場合はかなりシンプルに書くことができますね。

const fetchGet = async (url, param = "") => {

    const response = await fetch(`${url}?${param}`);

    if(response.ok) {

        const data = await response.text();

        // 何らかの処理

    } else {

        alert(`Error: ${response.status} ${response.statusText}`);

    }
}

以上です。
公式サイトに対応ブラウザについても記載がありますので、是非参考にしてみてください。

公式サイト:Fetch API – Web API | MDN

参考URL:
https://qiita.com/sotasato/items/31be24d6776f3232c0c0
https://ja.javascript.info/fetch
https://blog.katsubemakito.net/html5/fetch1

この記事がお役に立ちましたらシェアお願いします
2,902 views

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です