かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Ajax (XHR) まわりいろいろ試してみた。

前回FetchAPIを試してみたので、昨今のAjax? XHR?を色々ggって試してみました。(ホント簡単に

jQuery $.ajax

みんな大好きjQuery。お世話になった$.ajax!!
今もWordPressで"ほぅむぺぃじ"を作ったりするときには使うんじゃないでしょうか?

Promiseに似たDeferredオブジェクトが使えるようになってから非同期処理が書きやすくなった記憶です。

$.ajax({
  url: api_url,
  type: 'POST',
  dataType: 'json',
  data: {
    key: 'post_data'
  }
})
  .done(function(res, textStatus, jqXHR) {
    console.log(res); // 返されたデータ
  })
  .fail(function(jqXHR, textStatus, err){
    console.error(textStatus, err);
  });

typeでメソッドを指定し、dataに送信するデータを渡す、返されるデータ形式dataTypeで指定。という感じ。
返される値は$.ajax.done()の引数である関数の第一引数(data)に渡される。 jqXHRオブジェクトはXMLHttpRequestオブジェクトをjQueryで拡張したもの。 成功時のdone、失敗時のfail以外にもalwaysthenなど色々指定できるものがある。
cf. Deferred Object | jQuery API Documentation

XMLHttpRequest

いわゆるプレーンなJavaScriptの方法?

const onPostJSONbyXHR = (url, data) => {
  const jsonData = JSON.stringify(data);
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', url);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onload = () => {
      console.log(xhr.status);
      const data = JSON.parse(xhr.response);
      return resolve(data);
    };
    xhr.onerror = () => {
      console.log(xhr.status);
      return reject(xhr.statusText);
    };
    xhr.send(jsonData);
  });
};
onPostJSONbyXHR(api_url, post_data)
  .then((res) => console.log(res))
  .catch((err) => console.error(err));

Promiseを使ってXMLHttpRequestJSONをPOSTする部分を関数にしました。
JSONやFromDataなど、何を送るかでxhr.setRequestHeaderのヘッダー情報を自分で設定したり、データ形式に気を配るなど色々大変です。後、タイプ数が多くなるのが地味に辛い…
cf. XMLHttpRequest.send() | MDN

FetchAPI

こちらも生JSといえば、生JSってことになるのですかね?

fetch(api_url, {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  // String or Object
  body: JSON.stringify(post_data)
})
  .then((res) => res.json() )
  .then((data) => console.log(data))
  .catch((err) => console.error(err));

改めて見てみるとjQueryAjaxっぽいし、ほぼ同等な感じで使えそう。
cf. Fetch 概説 | MDN

axios

ライブラリなのでnpmでインストールしてrequireするかCDNで読み込ませるかして使う。

npm
$ npm install axios

読み込み

const axios = require('axios');
CDN
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

or

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
使い方

axios.get(url[, config]), axios.post(url[, data[, config]])な形式でリクエストを送れる

axios.post(api_url, {
  key: 'post_data'
})
  .then((res) => {
    // success
    console.log(res, res.data);
  })
  .catch(err) => {
    // error
    console.error(err);
  })
  .then(() => {
    // always
    console.log('> axios.post end');
  });

$.ajax, FetchAPIっぽい書き方もできる

axios(config)

axios({
  method: 'POST',
  url: api_url,
  data: {
    key: 'post_data'
  }
})
  .then((res) => console.log(res, res.data))
  .catch((err) => console.log(err))
  .then(() => console.log('> axios(config) end'));

axios(url[, config])

axios(api_url, {
  method: 'POST',
  data: {
    key: 'post_data'
  }
})
  .then((res) => console.log(res, res.data))
  .catch((err) => console.log(err))
  .then(() => console.log('> axios(url[, config]) end'));

superagent

こちらもライブラリ。結構メジャーらしいです。

npm
$ npm install superagent

読み込み

const request = require('superagent');
CDN
<script src="https://cdnjs.cloudflare.com/ajax/libs/superagent/4.1.0/superagent.min.js"></script>
<script>
const request = window.superagent;
</script>
使い方
request.post(api_url)
  .send({
    key: 'post_data'
  })
  .set('Accept', 'application/json')
  .then((res) => console.log(res, res.body))
  .catch((err) => console.error(err));

以前はPromiseライクでないfunction(err, res){...}でコールバックだったみたいですが、Promiseなthen, catchで書けるようになっていました。
v4ではOld-styleな.end(function(err, res){...})もサポートされているようです。

Old-style

request.post(api_url)
  .send({
    key: 'post_data'
  })
  .set('Accept', 'application/json')
  .end((err, res) => {
    if(err) {
      console.error(err);
    } else {
      console.log(res, res.body);
    }
  });

検索するとかつてはwrapperを作成してPromiseな書き方にしてしていたようです。

const postAPI = (post_data) => {
  return new Promise((resolve, reject) => {
    request.post(api_url)
      .end((err, res) => {
        if(err) {
          reject(err);
        } else {
          resolve(res.body);
        }
      })
  });
};
postAPI({key: 'post_data'})
  .then((res) => console.log(res))
  .catch((err) => console.error(err));

感想

ちょっと昔はjQueryAjax一択だった感覚なのですが、モダンな環境だと色々な選択肢があるなーと思いました。(ブラウザ間の差異が少なくなったから???)

フレームワークを使う場合はフレームワークに生えているリクエスト周りを使えばいいと思いますが、生えてなかったり、フレームワーク使ってなかったりする場合は個人的にFetchAPIaxiosWordPressでのほうむぺぃじ制作ならWordPressに入ってるjQuery使っての$.ajaxかなーという感覚です。

最近の傾向としては、このHTTP通信してJSONとかとってくるやつAjaxって言わないっぽい印象を持ちました。なんて呼ぶのが主流なんですかね? XMLHttpRequestからのXHR???
用語関係はソロフリーランスだと理解というか肌感が難しいデス。。。


[参考]

イラスト図解式 この一冊で全部わかるWeb技術の基本

イラスト図解式 この一冊で全部わかるWeb技術の基本