AJAX とは
Asynchronous JavaScript and XML (AJAX) は、XMLHttpRequest オブジェクトを使用して、XML や HTML、テキストファイル等の様々なフォーマットの情報を送受信することです。AJAX では、こういったことすべてをページを再読み込みすることなく「非同期」に実行できるというところです。つまり、ユーザーイベントによってページを部分的に更新できます。XML 文書を扱わなくとも、AJAX と呼ばれるようです。
AJAXの名前の元になったのは、Google Maps です。ページ全体を書き換えることなく地図を移動拡大できます。
AJAX の重要な機能は、次ので2つです。
- ページを再読み込みすることなくサーバにリクエストを送る
- XML 文書をパースして利用する
テキストファイルと xml ファイルにリクエストを出して、受信するサンプルを作ってみました。クリックすると、HTTP 通信をして受け取ったデータを表示します。
サンプル: AJAX のサンプル
AJAX のサンプルソースコードについて
AJAX のサンプルの HTML ファイルです。id='ajax_test1' の部分をクリックすると、テキストファイルを受信します。id='ajax_test2' の部分をクリックすると、後から説明する xml ファイルを受信します。
ajax_test.html のソースコード
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="content-style-type" content="text/css">
<script type="text/javascript" src="ajax_test.js"></script>
<script type="text/javascript" src="ajax_test_xml.js"></script>
<title>JavaScript AJAX のサンプル</title>
</head>
<body>
<p>AJAX でテキストファイルを読み込む <br>
<span id='ajax_test1' onclick="ajax_text('text_disp.txt')">テキストファイル</span><br>
↑ クリック<br><br>
AJAX で xml ファイルを読み込み表示 <br>
<span id='ajax_test2' onclick="ajax_xml('xml_disp.xml')">xml ファイル</span><br>
↑ クリック<br>
</p>
<div id="disp_frame">
<div id="data_frame" class="data_frame">
<span></span> <span></span> <span></span>
</div>
</div>
</body>
</html>
ajax_test.js は、テキストファイル text_disp.txt を HTTP 通信で受信する JavaScript です。id='ajax_test1' の部分をクリックすると、ajax_text() が実行されます。httpXmlRequest(target_url, success_func, error_func) は、target_url に httpXmlRequest して、成功した場合は success_func 関数を、失敗した場合は error_func 関数を実行します。httpObj.open('GET', target_url, true); で true をセットすると、非同期通信になります。本サンプルのメソッドは GET ですので、httpObj.send() の送信データは null になりまます。POST の場合は、送信データを記載します。
httpXmlRequest が成功した場合は、dispText() 関数で、httpObj.responseText でファイルのテキストデータを受け取ります。これで、通信が終わったときに、HTML が書き換わります。
ajax_test.js のソースコード
var httpObj; // HTTP通信用オブジェクト
var timerId; // HTTP通信用タイマーオブジェクト
var timeout_sec; // HTTP通信タイムアウト秒数
//通信成功時 テキストファイルの内容をHTLMに書き込み表示
function dispText() {
document.getElementById('ajax_test1').innerHTML=httpObj.responseText;
}
//通信失敗時
function httpError(error) {
alert(error);
}
//Ajax HTTP 通信
// 引数に与えられたURLにHTTPリクエストを行ない ファイルを取得する
/* target_url:リクエスト先のURL
success_func:HTTP通信完了時に参照する関数
error_func:HTTP失敗時に参照する関数
*/
function httpXmlRequest(target_url, success_func, error_func) {
try {
if(window.XMLHttpRequest) {
httpObj = new XMLHttpRequest();
} else if(window.ActiveXObject) {
httpObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
httpObj = false;
}
} catch(e) {
httpObj = false;
}
if(! httpObj) {
httpObjGenerateFail();//XMLHttpRequestオブジェクト生成に失敗
}
timeout_sec = 10;//タイムアウト時間設定(10秒)
timerId = setInterval('timeoutCheck()', 1000);//タイムアウト処理関数
httpObj.open('GET', target_url, true);
httpObj.onreadystatechange = function() {
if (httpObj.readyState == 4) {
//0未初期化,1リクエスト準備,2リクエスト完了,3受信中,4受信完了
clearInterval(timerId);
if (httpObj.status == 200) { //通信成功時
success_func();
} else { //通信失敗時
error_func(httpObj.status + ' : ' + httpObj.statusText);
return false;
}
}
}
httpObj.send('');//GET の時の送信データは null
}
// XMLHttpRequestオブジェクト生成に失敗した場合の処理
function httpObjGenerateFail() {
alert('ご利用のブラウザーでは、XMLHttpRequest は利用頂けません。');
return false;
}
// HTTPタイムアウト処理
function timeoutCheck() {
timeout_sec --;
if(timeout_sec <= 0) {
// タイマーをストップする
clearInterval(timerId);
// HTTPリクエストを中断する
httpObj.abort();
// エラーダイアログを表示
alert('タイムアウトです。');
return false;
}
}
//テキストファイルを読み込む
function ajax_text(target_url){
httpXmlRequest(target_url,dispText, httpError);
}
text_disp.txt のソースコード
ajax_test_xml.js は、xml ファイル xml_disp.txt を HTTP 通信で受信する JavaScript です。ajax_test_xml.js は、上記 ajax_test.js に追加された JavaScript です。httpXmlRequest() 関数は、共通です。
id='ajax_test2' の部分をクリックすると、ajax_xm() が実行されます。document.getElementById('ajax_test2').onclick = null; は、ajax_test2 の onclick を無効にしています。有効のままにすると、クリックするたびに後述するデータが追加されてしまいます。 httpXmlRequest が成功した場合は、dispXmlElemen() 関数で、今度は httpObj.responseXML で xml のデータを DOM ツリーのまま受け取ります。HTML に用意してあった、data_frame を複製し、そこに、xml のデータを貼り付けています。このままでもいいのですが、disp_frame.removeChild(data_frame); で複製して必要の無くなった部分を削除してみました。
このように、responseXML を使用すると XML 文書をパースして利用することができます。
ajax_test_xml.js のソースコード
function dispXmlElemen() {
xml = httpObj.responseXML;//xml を DOM ツリーで取得
var disp_frame = document.getElementById('disp_frame');
var data_frame = document.getElementById('data_frame');
//xml から取得した glroup 要素の配列
var glroup = xml.getElementsByTagName('glroup');
for (var i=0,L=glroup.length ; i<L ; i++){
//変数の初期化
var no ='';
var name = '';
var hobby = '';
//glroup 要素内の子要素の情報を取得
for (var j=0,M=glroup[i].childNodes.length ; j<M ; j++){
var child = glroup[i].childNodes[j];
if (child.tagName == 'no'){
if(child.firstChild){
no = child.firstChild.nodeValue;
}
}else if (child.tagName == 'name'){
if(child.firstChild){
name = child.firstChild.nodeValue;
}
}else if(child.tagName == 'hobby'){
if(child.firstChild){
hobby = child.firstChild.nodeValue;
}
}
}
//タグを子要素もふくめ複製
var n_data_frame = data_frame.cloneNode(true);
n_data_frame.removeAttribute('id');//id 属性を取り除く
n_data_frame.id = 'data_frame'+ i ;//新しい id をセット
//複製した3つの span に xml から取り出した値をセット
var spans = n_data_frame.getElementsByTagName('span');
spans[0].innerHTML = no;
spans[1].innerHTML = name;
spans[2].innerHTML = hobby;
//追加した要素をドキュメントに追加
disp_frame.appendChild(n_data_frame);
//n_data_frame.style.display = 'block';
}
//コピー用の data_frame 削除
disp_frame.removeChild(data_frame);
}
//xml ファイルを読み込む
function ajax_xml(target_url){
document.getElementById('ajax_test2').onclick = null;//onclickを無効にする
httpXmlRequest(target_url,dispXmlElemen, httpError);
}
xml_disp.xml のソースコード
<item>
<glroup>
<no>01</no>
<name>鈴木</name>
<hobby>旅行</hobby>
</glroup>
<glroup>
<no>02</no>
<name>佐藤</name>
<hobby>釣り</hobby>
</glroup>
<glroup>
<no>02</no>
<name>田中</name>
<hobby>散歩</hobby>
</glroup>
</item>
つぎは、HTML に XML が追加された結果です。
HTML に XML が追加された部分
<div id="data_frame0" class="data_frame">
<span>01</span>
<span>鈴木</span>
<span>旅行</span>
</div>
<div id="data_frame1" class="data_frame">
<span>02</span>
<span>佐藤</span>
<span>釣り</span>
</div>
<div id="data_frame2" class="data_frame">
<span>02</span>
<span>田中</span>
<span>散歩</span>
</div>
</div>