Ajaxを用いたJavaScriptによる動的通信を学ぶ。
以下のHTMLをコピペして適当な名前で保存し、ブラウザで開く。
<!DOCTYPE html>
<html>
<head>
<title>Ajax Test</title>
</head>
<body>
<h1 id="result"></h1>
<script>
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.github.com/users/hakatashi', true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
document.getElementById('result').textContent = data.bio;
}
};
xhr.send();
</script>
</body>
</html>
「Hello, World! I'm hakatashi.」と表示されれば成功。
Asynchronous JavaScript + XML の略⋯⋯らしい。
従来(~2005年)のWebではサーバーと通信を行うのはブラウザの仕事であり、ウェブページを開いた瞬間にそのページと必要なその他のリソースを読み込みに行く以外に通信が発生することがなかった。よってサーバーに新しいデータを送信したり、サーバーからの新しい情報を表示するためには、新たにページを開いて読み込み直す必要があった。
が、XHRの登場によりJavaScriptからブラウザと同じような通信を行うことができるようになり、ページ遷移することなく同じページの中で新たにデータを送信したり取得することができるようになった。
このような、ブラウザ上のJavaScriptから非同期的に行う通信のことを総称してAjaxと呼ぶ。
- ほげ
XMLHttpRequestの略。長らくAjaxを行うための唯一のAPIだった。
名前にXMLとついているのは、XML全盛期であった古の時代の名残であり、実際にはXMLに限らずテキストでもHTMLでもJSONでも画像でも、とりあえずブラウザからアクセスできるデータなら何でも通信できる。
古代時代に実装されたものということもあって、そのAPIは複雑で非常に扱いづらい。また非標準の実装がたくさん存在する。先ほどのコードを解説すると、
// コンストラクタでXHRを初期化する
const xhr = new XMLHttpRequest();
// 通信内容の初期化。第3引数は非同期で実行するかを表す。
xhr.open('GET', 'https://api.github.com/users/hakatashi', true);
// readystatechangeイベントにハンドラを登録する。
// readyStateにはXHRの現在の状態が記録されている。
xhr.onreadystatechange = () => {
// readyState === 4 はDONEを表す
if (xhr.readyState === 4 && xhr.status === 200) {
// JSONデータをパースする
const data = JSON.parse(xhr.responseText);
// データをDOMに格納
document.getElementById('result').textContent = data.bio;
}
};
// 送信開始
xhr.send();
となる。POSTしたりLong-Pollingを実装したりするとさらに複雑になる。
万能ライブラリjQueryの大量にある機能の一つ。複雑怪奇なXHRのAPIをラップしたもの。
上と(ほぼ)同じ処理をjQueryを用いて書くと以下のようになる。
$.ajax({
url: 'https://api.github.com/users/hakatashi',
method: 'GET',
json: true,
}).done(data => {
document.getElementById('result').textContent = data.bio;
});
// もしくは
$.get('https://api.github.com/users/hakatashi', {
json: true,
}).done(data => {
document.getElementById('result').textContent = data.bio;
});
// もしくは
$.getJSON('https://api.github.com/users/hakatashi').done(data => {
document.getElementById('result').textContent = data.bio;
});
ブラウザのAPIに最近実装されつつあるもの。既存のXHRを置き換える目的で開発された。
jQueryを用いなくてもAjax処理を簡潔に、そしてPromise的に書くことができる。
fetch('https://api.github.com/users/hakatashi')
.then(response => response.json())
.then(data => {
document.getElementById('result').textContent = data.bio;
});
フォト蔵APIを使って写真を検索するフォームを作ろう。
フォト蔵APIは外部サイトから叩けないようになっているので、photozou.hakatashi.comにプロキシサーバーを用意した。 (セキュリティ的によくないので実習が終わったら落とします)
例えば「猫」で画像検索するには、以下のURLを(GETで)叩く。 http://photozou.hakatashi.com/rest/search_public.json?keyword=%E7%8C%AB
ベースとして、以下のHTMLを使用する。 https://gist.github.com/hakatashi/6fab7eb84530eeedae5bbf8c3d065381
- それぞれの画像をHTMLに変換するときはtemplate関数を使う。
- 文字列をURLに突っ込むときはencodeURIComponent関数でエスケープする。
- $.paramを用いてもよい。
- 非同期処理の実行順序に注意!
- ページングを実装
- フォト蔵APIの他のオプションを指定できるようにする。
- copyrightオプションとか
- 他の画像検索APIと組み合わせて、結果を同時に表示する
- 例えばTumblr APIとか。
- APIキーを取得してJSONPでリクエストする必要がある。jQueryのjsonpオプションを使うのが楽。
- 例えばTumblr APIとか。
- XSS対策
https://gist.github.com/hakatashi/5d64a73d9cd113651d0148a1ec26d802
- 検索機能
- XSS対策
- ページング(オートページャ)
まで実装してます。