七転び八起きブログ

XMLHttpRequestの門を軽く叩いてみる

2005年03月07日   :: XML

XMLHttpRequestとJavaScriptの組み合わせで、今までのWeb Applicationのように画面が逐次読み込まれるのではない、画面変移の無いWebインターフェイスが実現できるとのこと。そしてそれを"Ajax(エイジャクス)"とも呼ぶらしいです。flickrもAjax使ってるとか。
 #参照;Ajax - Async Javascript with XmlHttpRequest: blog.bulknews.net「Ajax - Async Javascript with XmlHttpRequest」

AjaxXMLHttpRequestで検索すると、たくさん色々出てきます。使ってみると何か不安になるほどさくっと処理結果が返ってきてびっくりします。ローカルのアプリケーションと遜色ない感じです。興味津々。

さて、そんなAjaxも私にとっては高い壁なので、入門として、Guide to Using XMLHttpRequest (with Baby Steps) from WebPastiesの、リアルタイムにZipcodeから州名と都市名を返すフォームと言うのを見てみました。

以下はソース読みのメモです。備忘録。
オリジナルのサイトのソースを見ながら出ないと、ソースを上から順番に読んでるのではなく、作っている過程の流れに沿って読んでいるので、分かりにくいかも。

まず、HTTPオブジェクトを生成する関数です。
クロスブラウザの為に色々と分岐が行われています。

function getHTTPObject() {
var xmlhttp;
/*@cc_on

@cc_onとは、 条件付きコンパイルをオンにするということです。
あるメソッドをサポートしているか、などで、その後のスクリプトを分岐させられるのが、条件付きコンパイル。
 #参照;http://homepage3.nifty.com/aya_js/js3/js314.htm

@_win32 @_win16 @_mac
@_alpha @_x86 @_mc680x0 @_PowerPC
@_jscript @_jscript_build @_jscript_version
といった変数が最初から用意されていて、それぞれtrueかNaNを返します。
それぞれの条件付きコンパイル変数については
MicrosoftMSDN"JScript .NET"を参照。

ちなみにコメント内でも効果はあるので、コメント内にこのように書いたらダメ。
条件付きコンパイルは、非対応のブラウザでエラーが出ないように、通常コメント内に書きます。

@if (@_jscript_version >= 5)
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}

今回は@_jscript_version で判別。
バージョンが5以上だったら、Msxml2.XMLHTTPというXMLHTTPのオブジェクトを生成。
出来なかったら、Microsoft.XMLHTTPというオブジェクトを生成。

Using the XML HTTP Request objectによると、ActiveXObject("Msxml2.XMLHTTP") と ActiveXObject("Microsoft.XMLHTTP") は、Internet Explorer用で、IE内のMSXMLのバージョンが古いと後者しか使えないらしいです。


とりあえずここは、XMLHTTPオブジェクトを作れるかどうかのチェックらしいです。
色々なところを覗いてもほぼ同じ書き出しなので、決まり文句かも。

そして、

@else
xmlhttp = false;
@end @*/

バージョンが5より小さいか、先の@if節でのチェックに漏れたら、XMLHTTPオブジェクトは作れないとしてフラグにfalse入れます。

if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = false;
}
}
return xmlhttp;
}

XMLHTTPがfalseで、かつ、XMLHttpRequestオブジェクトが存在する場合は、XMLHttpRequest()コンストラクタでXMLHttpRequestオブジェクトを生成します。
要するにさっきの条件コンパイルは恐らくIEでしか動かないので(JScriptだし)、こちらがMozilla系用。

それもだめなら、falseを返して処理を終了。
そして、HTTPオブジェクトを生成します。

var http = getHTTPObject(); // We create the HTTP Object

ここから、実際にZipCodeから、州名等を呼び出す処理を加えていきます。
州名を返すプログラムは、ここでは getCityState.phpにしています。
パラメータで、ZipCodeを送ると、州名などが帰ってくるようになっています。getCityState.php?param=17534の様に。


これらをするため、まず、先ほどのgetHTTPObject() 関数の前に、handleHttpResponse()関数を書きます。

urlを変数に入れておきます。

var url = "getCityState.php?param=";

handleHttpResponse関数は、プログラムから帰ってきた州名と都市名をフォームに反映させるための関数です。
最初の"http.readyState == 4" は、httpdリクエストが完了した、つまりオブジェクトのダウンロードが完了したら処理をするという意味です。
readStateについては、
MicrosoftMSDN readyStateの項の、

uninitialized オブジェクトはデータでイニシャライズされていない
loading オブジェクトはデータをロード中である。
interactive オブジェクトはデータをロード中であっても、操作可能である。
complete コントロールは完全にロードされた。

という部分で、ここの上から順に1〜4に対応しています。
つまり、完全にダウンロードされたらということです。

サーバからのレスポンスが完全にローカルにダウンロードされたら、コンマをセパレータにしてレスポンスを配列にして、それぞれをフォームに入れます。ここは、このまんまです。

function handleHttpResponse() {
if (http.readyState == 4) {
// Split the comma delimited response into an array
results = http.responseText.split(",");
document.getElementById('city').value = results[0];
document.getElementById('state').value = results[1];
}
}

そして、この関数を呼び出すタイミングを見計らっているリスナーみたいな関数が、updateCityState() です。
こいつを、さきのhandlehttpResponse関数の下に加えます。

function updateCityState() {
var zipValue = document.getElementById("zip").value;
http.open("GET", url + escape(zipValue), true);
http.onreadystatechange = handleHttpResponse;
http.send(null);
}

zipというIDの振られたテキストボックスの中身をzipValueと言う変数に代入し、それを先ほどのphpプログラムに送ります。

そしてここがキモですが、onreadystatechangeというイベントハンドラを使って、先ほどのhandleHttpResponse関数を呼び出します。

onreadystatechangeというイベントハンドラはスクリプトなどでHTTPリクエストを送った際に発生するハンドラの様です。具体的にはXMLHttpRequest.readyStateが変化した場合に発生するらしいです。(参考;道楽日記 - 2005-03-01

詳しくはデベロッパーズコーナー:DOMプログラミング講座や、Hawk's W3 Laboratory : XML : XMLHttpRequestについてが良いと思います。

大本のupdateCityState関数は、onblurで呼ばれますので、
「ZipCode入力してフォーカス外す」
 ↓
「onblurイベント発生」
 ↓
「updateCityState関数を呼び出し、その中でhttpリクエスト」
 ↓
「onreadystatechangeイベント発生」
 ↓
「handleHttpResponse関数呼び出し」
 ↓
「レスポンスのダウンロード完了」
 ↓
「フォームにレスポンスを加工したものを代入」

という流れです。

こんな感じでしょうか。
自分は、http.openといった様な、HTTP オブジェクトについての理解が全く無いので、この辺りもちゃんと頭に入れておかないとまずそうですな…。

しかし、JavaScriptって気がついたらえらい色々出来るものになってるんですね。ウィンドウを動かすとかばっかり載ってる時代のハンドブックしか無いので、ジェネレーションギャップというか、久しぶりにあった従兄弟がムキムキになっていたとか、そういう気持ちです('A`)

XMLHTTPRequestについては
 #Hawk's W3 Laboratory : XML : XMLHttpRequestについて
 #MSXML SDK Overview

で、かなり幸せになれそうです。

■トラックバック

このエントリーのトラックバックURL:
http://www.7korobi8oki.com/mt/mt-tb.cgi/38

■コメントはこちらから

サイン・インを確認しました、 . さん。コメントしてください。 (サイン・アウト)

(いままで、ここでコメントしたとがないときは、コメントを表示する前にこのウェブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)


情報を登録する?


mail TOP