JavaScript
Ajax

NativeなJavaScriptでFetch APIを利用しAjaxを行う

昨今、jQueryが下火になって久しい。
そこでjQueryのajax関数を使わずNativeなJavaScriptでどのようにAjaxを行うのかを調べたので備忘録として記述していく。

TL;DR;

フロントエンドの規模が小さく、古いブラウザのサポートを気にする必要がないプロジェクトでは今後はFetchAPIを利用していったほうが良さそう。

従来のNativeなAjax

XMLHttpRequest

過去のやり方であればXMLHttpRequestを使う方法も用意されていた。
しかし、これはjQueryのAjaxに慣れてしまった人には違和感も覚える人もいるだろう。

var request = new XMLHttpRequest();
request.open('post', '/foobar', true);
request.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
request.onload = function (event) {
    if (request.readyState === 4) {
        if (request.status === 200) {
            console.log('OK');
        } else {
            console.log('Bad');
        }
    }
};
request.onerror = function (event) {
  console.log('Error Occurred');
};
request.send('foo=1&bar=2');

Ajax

jQueryのAjaxなら以下のような書き方になる。
XMLHttpRequestと比較すると、 どこに、どのようにアクセスし、その結果どういう処理をするのか という一連の流れをメソッドチェーンで追えるのでわかりやすいのではないかと個人的には思っている。
XMLHttpRequestは特に どのようにアクセスする という記述が散っているので読み辛い。

$.ajax({
    url: '/foobar',
    type: 'POST',
    data: {
        'foo': 1,
        'bar': 2,
    }
})
.done(function (data, status, xhr) {
    if (xhr.status == 200) {
        console.log('OK');
    } else {
        console.log('Bad');
    }
})
.fail(function (err) {
    console.log('Error Occurred');
})

Fetch API

そこでFetchAPI。

最近のブラウザなら実装されている(当然ながら古いブラウザ対応したいなPolyfillとかで対応してあげる必要あり
記述もほぼAjaxと同様に行えてjQueryから移行してくる人も理解しやすいのではないだろうか。

fetch('/foobar', {
  method: 'POST'
  body: 'foo=1&bar=2',
  headers: new Headers({'Content-type' : 'application/x-www-form-urlencoded' }),
})
.then(function (response) {
    if (response.status === 200) {
      console.log('OK');
    } else {
      console.log('Bad');
    }
})
.catch(function (err) {
    console.log('Error Occurred');
});

具体例

RestfulなAPIを叩いて帰ってきたレスポンスのjsonを扱うような具体的な実装は以下のような感じになる。

fetch('/foobar', {
    method: 'POST'
    body: 'foo=1&bar=2',
    headers: new Headers({'Content-type' : 'application/x-www-form-urlencoded' }),
    // リクエストパラメータをJSON形式で渡すならこんな書き方もできる
    // body: JSON.stringfy({
    //     "foo": 1,
    //     "bar": 2,
    // }),
    // headers: new Headers({'Content-type' : 'application/json' }),
})
.then(function (response) {
    if (response.status !== 200) {
      throw 'なにかエラーログ的なもの'; // catchに飛んでログが吐かれる
    }
    return response.json(); // promiseが帰ってくるので後続のthenで処理する
})
.then(function(objs)) {
    // objsにはresponse.bodyにあるjson stringがパースされたものが入っている
    // do something ...
}
.catch(function (err) {
    console.log(err);
});

参考