JavaScriptで非同期通信を行うには、jQueryのajaxメソッド/getJSONメソッドなどを使用するとよい。通信完了時の処理はメソッドチェーンを使って記述できる。
JavaScriptでそのWebページと同じサイトからデータを非同期に取得するにはXMLHttpRequestオブジェクトを使うが、そのコーディングは少々面倒だ。何とかならないだろうか? jQueryに用意されているajaxメソッド(あるいはgetメソッドなど)を使うとコードを簡潔に書ける。
本稿では、ajaxメソッドを使って非同期にデータを取得する方法を解説する。
最近のWebブラウザは、ローカルファイルシステム上では大抵Ajaxが動作しない。そこで、本稿のコードを試すには、Webアプリの開発環境が必要になる。例えば、無償のVisual Studio CommunityでWebサイトのプロジェクトを作成するなどしてほしい。
次に、サーバサイドからデータを提供する仕組みを用意する。といっても、非同期通信を試してみるだけなら常に同じデータを返しても支障はないので、固定的なファイルをWebアプリに追加しておけばよい。ここでは「data.json」というファイルを追加した(次のコード)。
{"foreground":"white", "background":"blue"}
最後に、非同期通信を試すためのHTMLページを追加し、ボタン(id="startButton")とテキストエリア(id="result")を配置しておく。また、jQueryを使えるようにし、テキストエリアにメッセージを表示するためのaddMessage関数と、ボタンのクリックイベントハンドラーも用意しておく(次のコード)。
<!DOCTYPE HTML>
<html>
<head>
<title>.NET TIPS #1140</title>
<script type="text/javascript"
src="http://code.jquery.com/jquery-2.2.3.js"></script>
<script type="text/javascript">
$(window).load(function(){
"use strict";
function addMessage(msg) {
// メッセージの先頭に時刻を追加する(mm:ss.fff)
var dt = new Date();
var min = ("0" + dt.getMinutes().toString()).slice(-2);
var sec = ("0" + dt.getSeconds().toString()).slice(-2);
var mSec = ("00" + dt.getMilliseconds().toString()).slice(-3);
var time = min + ":" + sec + "." + mSec;
var s = time + " " + msg + "\n";
$("#result").text($("#result").text() + s);
}
// ボタンのクリックイベントハンドラー
$("#startButton").click(function (e) {
$("#result").text(""); // テキストエリアをクリア
addMessage("クリックイベントハンドラーの先頭");
// ここに非同期通信のコードを書いていく
addMessage("クリックイベントハンドラーの末尾");
});
})
</script>
</head>
<body>
<h1>ajax(非同期通信)</h1>
<div>
<p>同じWebサイトにあるデータを非同期で読み取る
<button id="startButton">非同期処理開始</button></p>
<p>処理結果<br />
<textarea id="result" rows="10" cols="80"></textarea>
</p>
</div>
</body>
</html>
ajaxメソッドは、XMLHttpRequestオブジェクトを利用して非同期通信を行うための汎用的なメソッドである。そのコーディング方法は数種類あるが、本稿ではメソッドチェーンの書き方を紹介する。
また、特定の目的に特化したメソッドも用意されている。JSONデータを取得するためのgetJSONメソッドや、POSTリクエストをするためのpostメソッドなどだ。いずれのメソッドで行う処理も、ajaxメソッドで可能なのだが、より簡潔に記述できる。
URLなどを指定してajaxメソッドを呼び出し、その後にチェーンしたdoneメソッドやfailメソッドで結果を処理すればよい。前述したボタンのクリックイベントハンドラー内の「ここに非同期通信のコードを書いていく」とコメントした部分に、次のコードを記述する。
$.ajax({
type: "GET", // 省略可(省略時は"GET")
url: "./data.json",
dataType: "text", // 省略可(省略時はMIMEタイプから推定)
cache: false, // 省略可(省略時はtrue)
timeout: 10000 // 省略可
})
// 成功時
.done(function (data, textStatus, jqXHR) {
addMessage(textStatus + ": status=" + jqXHR.status);
// 「dataType: "text"」と指定すると、dataはプレーンテキスト
addMessage(data);
})
// 失敗時
.fail(function (jqXHR, textStatus, errorThrown) {
addMessage("fail! " + jqXHR.statusText
+ ", status=" + jqXHR.status);
});
実行してみると次の画像のようになる。結果表示より先に、イベントハンドラー末尾で出力しているメッセージ「クリックイベントハンドラーの末尾」が表示されているので、実際に非同期で通信が行われたことが分かる。
上のコードで「dataType: "text"」のところを「dataType: "json"」に変えると、成功時の第1引数dataはJSONフォーマットの文字列から変換されたオブジェクトになる(次のコード)。dataTypeの指定を省略すると、jQueryはMIMEタイプから型を推定する。サーバが返してくるMIMEタイプを勘違いしていると第1引数dataが思わぬ型になっていて首をひねることになりかねないので、dataTypeの指定は省略しない方がよいだろう。
$.ajax({
type: "GET", // 省略可(省略時は"GET")
url: "./data.json",
dataType: "json", // 省略可(省略時はMIMEタイプから推定)
cache: false, // 省略可(省略時はtrue)
timeout: 10000 // 省略可
})
// 成功時
.done(function (data, textStatus, jqXHR) {
addMessage(textStatus + ": status=" + jqXHR.status);
// dataType: "json"と指定すると、dataはオブジェクト
addMessage("fg:" + data.foreground + ", bg:" + data.background);
})
// 失敗時
……省略……
jQueryで同じサイトからデータを非同期に取得するにはajaxメソッドを使う。非同期処理になるが、本稿で示したようにメソッドチェーンの形で後続の処理を書けるのでネストが深くなりすぎることはない。また、特定の処理に特化したメソッド(getJSONメソッドやpostメソッドなど)が用意されているので、実際の開発では適したメソッドを選んでほしい。
カテゴリ:JavaScript 処理対象:DOM
カテゴリ:オープンソース・ライブラリ 処理対象:JavaScript
使用ライブラリ:jQuery
関連TIPS:Visual Studioで静的HTMLページのJavaScriptコードをデバッグするには?
関連TIPS:ファイルをダウンロードさせるには?[JavaScript]
関連TIPS:DOMの子要素を探索するには?[JavaScript/jQuery]
関連TIPS:UI要素の表示/非表示を判別するには?[JavaScript/jQuery]
Copyright© Digital Advantage Corp. All Rights Reserved.