今どきのAJAX、fetch APIってなんぞ?

この記事はアンテクアドベントカレンダー2022の9日目の記事です。

https://adventar.org/calendars/7821

気がつけば次の順番が回ってきましたサーバーサイドエンジニアのレイジー先生です。

サーバーサイドエンジニアのはずですが今年のアドベントカレンダーではサーバーサイドの記事を書く気がないようです。PHPよりJSのほうが好きなんですよ、ぼかぁ。

というわけで前回のjQueryの話に引き続いて今回はFetch APIの話をします。

AngularJSの話を書くといったな、あれは嘘だ

Fetch API、実務で使ったことないんですけどね。

細かいことは気にせずに行ってみましょう! ひぁうぃごー!!

そもそもAJAXとは

前回の記事でも書きましたがAJAXは「Asynchronous JavaScript And XML」の略でして、「JavaScriptからXMLデータを非同期で取ってこよう!」という機能です。

実はこれ、もともとIE5が一番最初に導入されたもののようです。ActiveXの機能でした。

https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest_in_IE6

なのですが、こりゃ便利だな、ってことになって急速に標準化されたのだそうで、そのうちNetscapeNavigatorにもXMLHttpRequestとして実装されたりしました。そういえばwebブラウザはもともとこういうことは自力でできなかったのでFlashとかJavaAppletなんかを作ってページに埋め込んだりしてたのですよ。

そのへんの歴史はこちらのブログにいい感じにまとまっていたので読んでみてください。

https://blog.jxck.io/entries/2022-09-30/XMLHttpRequest.html

XMLHttpRequestは書くのが大変

便利でイカす見た目のAJAXは昔はXMLHttpRequest(以下XHR)をせっせと書かないといけなくて、みんなめんどくせぇなと思っていたものです。

MDNに載ってたサンプルコードはこれですね。

function reqListener() {
  console.log(this.responseText);
}

const req = new XMLHttpRequest();
req.addEventListener("load", reqListener);
req.open("GET", "http://www.example.org/example.txt");
req.send();

パッと見7行なんで可愛いもんだな、って感じですが、毎回イベントリスナーセットしたりすんのか、ダリィな、となるのが人間ってもんです。

そこで現れたjQueryがとんでもなくあっさり書けるもんだから、みんなこっちに行き、みんなが使うってことはここがセキュリティホールになったわけで、あとはご察しですね。

ネイティブのJSでも(割と)簡単に書けるようになった

MDNのfetchAPIの使い方のページを見ながら早速上のXHRをfetchで書き直してみましょう。

fetch('http://www.example.org/example.txt')
  .then((response) => response.text())
  .then((text) => console.log(text));

こんだけですよ!

なんか then が2回来るのがクセありますが、ここまであっさり書けるならしめたもんですよね!

awaitを使うともっとあっさり書けます。

const text = await fetch('http://www.example.org/example.txt').text();
console.log(text);

Axiosはなんでまだ使われているの?

Vue.jsのv2が出てきたときにVue.jsが自前のAJAX通信モジュールを捨ててAxiosを推奨するようになってから、Axiosが次世代のAJAX通信ライブラリとして急にメジャーになりました。

https://github.com/axios/axios

とはいえ、こんなにあっさり書けるfetchAPIがネイティブのJSにあるなら、別にAxios使わなくても良くね?って思いますよね。

Axiosはもっと直感的に使えるのですよ。

import axios from 'axios';

axios.get('http://www.example.org/example.txt')
  .then((response) => console.log(response.data));

GETだとそんなに差を感じないのですが、これがこと POST になると歴然とします。

import axios from 'axios';

const data = {
  hoge: 'fuga'
};

// fetchの場合
fetch('http://www.example.org/hoge', {
  method: 'POST',
  body: JSON.stringfy(data)
});

// axiosの場合
axios.post('http://www.example.org/hoge', data);

そう思うとまあこりゃ手放せないよねー、ってなりますよね。

まあでももう手放そうと思うんですけど。(やらかされたので)

おわりに

というわけで今回はfetch APIの話でした。

次はちょっと日が空きますが、今年の最終回になります。

またお会いしましょう。

TAGS使用タグ一覧