InfoTech
Ajax 基礎
「Ajax」とは何か?
「Ajax」はAsynchronous JavaScript + XMLの略称であり「エイジャックス」と読む。間違っても「アジャックス」とか人前で言っては
なりません。「エージェーエーエックス」等とのたまうのは、もってのほかです。
ちなみに
「Ajax」という言語や開発環境は存在せず、JavaScript の組み込みクラスである XMLHttpRequest
を利用した非同期通信を利用して、ウェブブラウザ上で非同期的なインタフェースを実現することを総称して「Ajax」と呼んでいます。
なお、本企画ではJavaScriptと何らかのサーバサイド言語を大まかに理解しているかたを想定して書いています。ご了承ください。
とりあえず、やってみる?
著者の所属するミラクル産業では、古き時代よりプログラム言語を習得する際には、先ず「足しザウルス」を作るところから始めるという習しがあります。今回もそれに従って「足しザウルス 」を作ることから始めます。「足しザウルス」が何かご存知で無い方に説明しますと、「足しザウルス」とは「ユーザーから2回の数値入力を受け付け、その2つの数値を加算してユーザーに返す」という処理を行うプログラムの総称であります。
とりあえず、作成したのがコレです。
数値を入力して「計算」ボタンを押してみてください。
JavaScriptだけでも十分に処理可能なプログラムですが、サーバーに足し算のリクエストを出して計算結果を受け取って表示するという、非常に無駄なシステムとなっています。操作していただけると判りますが、サーバとの通信を行ってもペー
ジのリロードが行われていないというのがAjaxの特徴です。
クライアント側(ブラウザ)の処理は?
Ajaxの構造上、サーバ側よりもブラウザ側(JavaScript)のコーディングの方が煩雑になります。
[ajax_01.js] 001 function HttpResponse() {
002
003 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
004 var xmlDoc = xmlHttp.responseXML;
005
006 if (xmlDoc.documentElement) {
007 var z = xmlDoc.getElementsByTagName('z').item(0).firstChild;
008 } else {
009 var z = 0;
010 }
011
012 document.getElementById('z').value = z.data ;
013
014 }
015 }
016
017 function HttpRequest() {
018
019 var x = document.getElementById('x').value;
020 var y = document.getElementById('y').value;
021
022 xmlHttp.open('GET', 'http://shoppers-jp.com/tech/ajax_01.cgi?x=' + x + '&y=' + y , true);
023 xmlHttp.onreadystatechange = HttpResponse;
024 xmlHttp.send(null);
025
026 }
027
028 function getXmlHttpObject() {
029 var xmlhttp;
030 /*@cc_on
031 @if (@_jscript_version >= 5)
032 try {
033 xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
034 } catch (e) {
035 try {
036 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
037 } catch (E) {
038 xmlhttp = false;
039 }
040 }
041 @else
042 xmlhttp = false;
043 @end @*/
044 if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
045 try {
046 xmlhttp = new XMLHttpRequest();
047 xmlhttp.overrideMimeType("text/xml");
048 } catch (e) {
049 xmlhttp = false;
050 }
051 }
052 return xmlhttp;
053 }
054
055 var xmlHttp = getXmlHttpObject();
056
|
HttpRequestファンクションでは、formのデータを読み込み、XmlHttpを利用してサーバプログラム ajax_01.cgi を起動します。
23行目で、通信ステータスが変更された時の呼び出しファンクション(HttpResponse)を指定しています。
getXmlHttpObjectファンクションの「/*cc_on」で始まっているコメント部分は必要ですので削除しないようにしてください。オブジェクトの生成方法のブラウザ毎の差異を吸収するために、このような書き方になっています。あんまり悩まずに呪文として覚えておいてください。
HttpResponseファンクションは、通信が完了したことを確認して、受信したXMLから必要な要素を取り出し、テキストボックスに入れます。
| [参考] readyStateの値について。 | |
|
0 (UNINITIALIZED) |
オブジェクトは、作成されていますが、まだ、初期化されていません (open メソッドは呼ばれていません)。 |
|
1 (LOADING) |
オブジェクトが作成されましたが、まだ、send メソッドは呼ばれていません。 |
|
2 (LOADED) |
send メソッドは呼ばれましたが、statusとヘッダはまだ届いていません。 |
|
3 (INTERACTIVE) |
いくつかのデータを受け取りました。この状態ではresponseBodyやresponseTextプロパティはエラーを返すでしょう。それは、statusとレスポンスヘッダがまだすべて届いていないからです。 |
|
4 (COMPLETED) |
すべてのデータを受け取りました。responseBody と responseText プロパティの完全なデータが利用可能です。 |
[ajax_01.html(より抜粋)] 001 <form action="post"> 002 <p>足しザウルス for Ajax<br> 003 <center> 004 <input type="text" size="5" name="x" id="x"> + 005 <input type="text" size="5" name="y" id="y"> = 006 <input type="text" size="5" name="z" id="z"> 007 <input type="button" value="計算" onClick="HttpRequest()"><br> 008 </center></p> 009 </form> 010 |
記述するまでも無いのかも知れませんが、htmlファイルのformの記述は以上のようになっています。
通信が必要なタイミングで「HttpRequest()」を呼び出す書き方をすれば、どのような形でも構いません。
サーバ側はどうなってるの?
基本的にクライアントから投げられたパラメータをもとに処理(DBアクセス等)を行い、結果を適当にXML形式で返してあげます。
試しに、http://shoppers-jp.com/tech/ajax_01.cgi?x=10&y=20
をクリックしてみてください。「<z>30</z>」との記述のXMLが返ってきます。
勘の良い方なら全てが判ったと思いますが、このようにサーバが返したXMLを先ほどのJavaScriptの7行目の「xmlDoc.getElementsByTagName('z').item(0).firstChild」で必要な部分を拾い出して使用するという仕掛けです。Ajaxと言っても、基本は単純ですXMLなので返すパラメータを複数にすることも簡単ですね?
[ajax_01.html(より抜粋)] 001 #!/usr/bin/perl
002
003 # Ajax サンプル1
004
005 get_form();
006
007 my $x = $FORM{'x'};
008 my $y = $FORM{'y'};
009
010 my $z = $x + $y;
011
012 print "Content-Type: text/xml\n\n";
013 print '<?xml version="1.0" standalone="yes"?><tashi><z>' . $z . '</z></tashi>';
014
015 sub get_form {
016 read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); # POST
017 $buffer .= $ENV{'QUERY_STRING'}; # GET
018
019 @pairs = split(/&/,$buffer);
020 foreach $pair (@pairs){
021 ($name,$value) = split(/=/,$pair);
022 $value =~ tr/+/ /;
023 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2",$1)/eg;
024 $value =~ s/\x0D\x0A/\r/g;
025 $FORM{$name} = $value;
026 }
027 }
028
|
クライアント側に合わせて、適当にXMLを作成して送ることができれば、どのように記述しても構いません。
