AJAXというメソッドが世に出てからしばらく経ちますが、一般のウェブサイトなどで活用されたわけでもなかったが、ここ最近になってWebアプリケーションの中でUI/UXの重要性がたかまったことで、注目をより集め始めました。AJAX自体はプログラミング言語ではなく、Webページに対してJavaScriptを活用する新しい方法と呼べると思います。この新しいテクノロジーはWebページをより速くしたりユーザーフレンドリーにしたりと、機能全般的により効率のよいものにしてくれます。
AJAXは「Asynchronous JavaScript and XML」の略で、JavaScriptを経由してサーバとの双方向のやり取りや更新に使用され、画面遷移せずとも部分的な更新を可能にしてくれます。今回のアーティクルではWebサイトにAJAXを実装する為に必要な基本的なことをカバーしていきたいと思います。
この記事は、http://www.onextrapixel.com/の許可を得て、翻訳しています。一部変更して翻訳している部分もある場合があります。オリジナルの記事はここよりご覧いただけます。
JavaScriptを知ってれば余裕♪
もしJavaScriptの基本を少しでも知ってたら、AJAXを理解するのにそう時間はかからないと思いますよ。JavaScriptを使えば、ユーザーと相互作用(インタラクト)するようなWebページを作ることが出来ますよね。ユーザーとのインタラクションに基づき、必要な時にサーバのレスポンスに応じてWebページの内容を送信、受信、更新することが出来ます。
ではここにシンプルなボタンがあるとしましょう。そしてこのボタンはWebページの何かしらのデータを更新する為に使われるものとします。勿論更新する為のデータ収集用の入力フィールドもあると想像してください。
<button onclick="updateProfile()" type="button">Update</button>
上記のボタンコードで分かるように、ボタンをクリックすると「updateProfile()」というJavaScriptの関数を呼び出すことが出来ます。もし既にJavaScriptをご存知でしたらもうここら辺は余裕だと思います。scriptタグ間で定義されている関数が呼び出されます。
<script type="text/javascript"> function updateProfile(){ // JavaScript code to be executed } </script>
こういったscriptタグやその内部のコードなどは、bodyタグの直前に配置するのが通例となっています。またサイトの構築方法やページに対する特別なニーズにもよりますが、JavaScriptはヘッダー内に配置することも可能です。勿論JavaScriptファイル(拡張子.js)に配置して、ヘッダー部分で読み込むのが無難です。
さて、これでボタンが押された時に実行したいコードを関数内に配置出来ます。この辺も特に目新しいことはないかと・・・。従来のJavaScriptではサーバからのデータをそれ以上必要としない限り、そのページ内に既に存在しているコンテンツを自由に操作することが出来ましたよね。Freelance Finances Calculatorなんかは、JavaScript使用例の良い例だと思いますよ。
もし更にサーバからの情報が必要な場合は、サーバサイド・スクリプト言語を使ってページを再読込みさせる必要がありました。ここでAJAXの出番です!「updateProfile()」関数内にJavaScriptを介してサーバと通信する為のAJAXコードを記述すれば、ページを再読込みすることなく、必要に応じてサーバ上のデータを取得、更新、削除することが出来るようになります。
<script type="text/javascript"> function updateProfile(){ // JavaScript code to be executed // AJAX code will go here as well! } </script>
XMLHttpRequestとActiveXObject Objects
AJAXを使用するにはまずブラウザに「サーバと通信しますよ」と伝える必要があります。JavaScriptにはAJAXが動作する為の手助けとなるオブジェクトが2つあります。それが「XMLHttpRequest」と「ActiveXObject Objects」です。これらのオブジェクトはJavaScriptによるオブジェクト指向の基礎となる部分なので、今ここでオブジェクト指向の概念を理解したり実装する必要はありません。またそれは追って説明していきますね。
どちらのオブジェクトもWebページの裏側でサーバとデータを交換したり処理したりと同じことを行いますが、サポートするブラウザが異なります。
「AJAXを使いますよ」とブラウザに伝えるには、以下のコードを使用します。(W3Schoolsから拝借)
<script type="text/javascript"> function updateProfile(){ // Create a variable to refer to our request object: var xmlhttp; if (window.XMLHttpRequest){ // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); }else{ // code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } } </script>
上記のコードは極めてシンプルです。まずオブジェクトを保持する変数を作成します。このオブジェクトは「XMLHttpRequest」か「ActiveXObject Objects」のどちらかになります。(けれどどちらもすることは同じです。)もしブラウザがwindow.XMLHttpRequest経由で「XMLHttpRequest」をサポート可能と検出出来るならオブジェクトを「XMLHttpRequest」に設定します。そうでないなら「ActiveXObject Objects」に設定します。
WEBサイトでAJAXを使用する場合は、いつもここからスタートすることになります。もし複数の関数を使用している場合、全関数の前にこのコードを宣言するのはあまりいいアイデアではないと思います。複数の関数を使用する場合は、ページロード時に変数を設定する方が効率的だと思います。
サーバからのレスポンス受信
これでAJAXをブラウザで使用する為の準備は整ったので、ここからがお楽しみパートです。サーバとの通信に移りましょう。ブラウザによってどのリクエストオブジェクトが使用されようと、AJAXを介してサーバから情報を取得したり送信したり操作する為に使用可能な事前定義された関数があります。
1つ目の事前定義プロパティは「onreadystatechange」です。何をするプロパティかと言うと、もうそのまま読んで字のごとくなのですが「readyState」が変更されると、自動的に保持している関数をコールしてくれます。「readyState」は単に「処理中」「ダウンロード中」「完了」といったオブジェクトの状態を示します。
xmlhttp.onreadystatechange = function(){ // This code will be executed each time the readyState changes }
「readyState」はそれぞれ0から4の番号によって定義されているので、サーバの処理状況によって割り振られる数字と照し合せれば状態を確認することが出来ます。
- ajaxRequest.readyState == 0 // request not initialized
- ajaxRequest.readyState == 1 // server connection established
- ajaxRequest.readyState == 2 // request received
- ajaxRequest.readyState == 3 // processing
- ajaxRequest.readyState == 4 // completed and response is ready
例えばデータやアクションを要求後、返答が返せる状態になった時だけコードを実行したいというような場合は、「readyState」の状態が4であるかどうか確認すればいいのです。
xmlhttp.onreadystatechange = function(){ // This code will be executed each time the readyState changes if(ajaxRequest.readyState == 4){ // This code will be executed if our request // is completed } }
また「responseText」や「responseXML」プロパティを使えば、要求しているデータにアクセスすることが出来ます。「responseXML」はXMLベースのデータを取得する為に使用し、「responseText」はテキストデータを取得する為に使用します。再びここで基本的なJavaScriptが登場しまして、この2つのプロパティはDIVでも何でもいいのですがサーバからの返答を割り当てるのに使うことが出来ます。
xmlhttp.onreadystatechange = function(){ // This code will be executed each time the readyState changes if(ajaxRequest.readyState == 4){ document.getElementById("myData").innerHTML=xmlhttp.responseText; } }
これで背後に潜むロジックが大体理解出来たのではないでしょうか。勿論最初に要求したいコードを示しておかないと、何の役にも立ちません。まず私たちのリクエストを処理する関数を作成する必要があります。上記のコードは単純にリクエスト送信後のオブジェクトの状態を表示しているに過ぎません。
サーバへのリクエスト送信
サーバからの返答受信の時と同じように、サーバへのリクエスト送信時にも事前定義されたプロパティと関数あります。新しい情報を送信する時や、情報を操作する時、またWebアプリケーションで動作するイントラクションを送信する時などに、私たちはリクエストをサーバに対して送信しています。リクエスト送信後は先ほど「onreadystatechange」を使って作成した関数を使って結果を求めればいいだけです。
AJAXを介してサーバにリクエストを送信するには、下記のような2つのメソッドを使用します。
xmlhttp.open("GET","ourPHPCode.php",true); xmlhttp.send();
1つ目の事前に定義されている関数は「open()」です。サーバとの通信にどのサーバサイドスクリプトを使用するか定義しておきましょう。サーバサイドスクリプトは2つ目のパラメータとして設定してありページをリフレッシュしなくても処理されます。他の因数に関しては後程説明しますね。
サーバサイドスクリプトの「ourPHPcode.php」ファイルの中には、サーバが動作する為の更に詳しい指示が記述してあり、AJAXが「open()」メソッドによりサーバサイドスクリプトをオープンした後、「send()」メソッドを使ってファイル内の詳しい指示を送信することが出来ます。
<script type="text/javascript"> function updateProfile(){ // Let's first create our request object: var xmlhttp; if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); }else{ xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } // This code will be executed each time the readyState changes xmlhttp.onreadystatechange = function(){ if(ajaxRequest.readyState == 4){ document.getElementById("myData").innerHTML=xmlhttp.responseText; } } // We'll send any data to the server through our request object xmlhttp.open("GET","ourPHPCode.php",true); xmlhttp.send(); } </script>
open()の詳細説明
AJAXを経由してサーバに送信する為にファイルを開く時、最も重要な項目はサーバサイドファイルへのリンクです。この他にリクエスト送信方法(メソッド)とasync(非同期通信を行うか)を示すパラメータを持っています。
open(method,file,async); Example: open("POST", "myFile.aspx", false);
「open()」関数用のメソッドとしてはGETとPOSTがあります。もしPHP(他にも何でも似たような言語)やHTMLのフォームを使ってのデータ送信の知識をお持ちなら、概念は殆ど同じです。大体どのような状況でもGETを使用することは可能で、HTMLフォームと同様にURLに組込ませて値を送信することも出来ます。
open("GET", "ourPHPCode.php?email=test@test.com&firsname=Johnny&lastname=Smith", false);
GETはしばしキャッシュされた結果を持ってきてしまうことがあり、これだとあまり使えない情報ですよね。それでもGETを使いたいのであれば、ユニークIDを付加してフレッシュな新URLを使うことにより先ほどの問題を回避することが出来ます。
open("GET", "ourPHPCode.php?x=", false);
けれどPOSTの方がGETよりも安全であると言えると思います。それにPOSTならばサイズの制限もありません。もしパスワードなど機密情報を取り扱っているのであれば、POSTを使うべきです。
最後のパラメータのAsync(非同期通信を行うか)の値は「true」か「false」が入ります。殆どの場合「true」を選択する事の方が多いのではないでしょうか。「false」は小規模なリクエストの時に使われることもあります。このAsyncを「true」に設定すると言うことは、簡単に言うとAJAXがサーバからのレスポンスを待っている間に他の作業をすることが出来るということです。(なのでこちらが推奨されています。)
サーバサイド言語
サーバサイドスクリプトからの情報要求やその応答処理と言ったAJAXへの設定が終わったら、サーバサイドスクリプトに関してはこれと言って特別なことは何もありません。コードも同じですし、構文もいつもと同じように書けば問題ありません。AJAXがすることは仲介役としての手助けです。AJAXが面倒な部分を請け負ってくれているおかげで、私たちはページリフレッシュの手間を省き、またサーバサイドスクリプトがサーバと通信している間に他のファンクションを実行することが出来ます。
試しにフォーム入力を変更したら(PHPを介して)文字列をエコー表示させるようなサンプルを作ってみましょう。
AJAXとJavaScriptを加えたHTMLファイルは以下のようになります。
<html> <head> <script type="text/javascript"> function updateProfile(){ // Let's first create our request object: var xmlhttp; if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); }else{ xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } // This code will be executed each time the readyState changes xmlhttp.onreadystatechange = function(){ if(ajaxRequest.readyState == 4){ document.getElementById("myData").innerHTML=xmlhttp.responseText; } } // We'll send any data to the server through our request object xmlhttp.open("GET","ourPHPCode.php",true); xmlhttp.send(); } </script> </head> <body> <input name='firstName' onChange='updateProfile()' /> <div id="myDate"></div> <!-- Our response will be placed into the div above, thanks to JavaScript's "innerHTML" property. --> </body> </html>
PHPファイル(ourPHPCode.php)の中身です。
<?php echo "The input field was changed."; ?>
JavaScriptの「onChange」イベントを使ってJavaScript関数の「updateProfile()」をトリガーします。この関数では既にAJAXのセットアップは全て完了しており、エコー表示用のPHPファイル(ourPHPCode.php)へのリクエスト送信もしています。なので入力フィールドに変更が加わったら、AJAXの恩恵に与って文字列をエコー表示することが出来ます。ページをリフレッシュしたり、サーバから遅いレスポンスを待つ必要はありません。
はっきりいってこのサンプルはとてつもなくシンプルで、全くもって無意味です。これは単にAJAXを使ってどの様にサーバサイドスクリプトとHTMLページをコネクトするかと言う基本レベルのサンプルに過ぎません。PHPを使えばフォームからデータを取得することが出来ます。(例えばopen()関数でPOSTを使ったとしたら、PHPの$_POST変数を使って情報を取得することが可能です。)他にもその情報を操作したり、サーバへ送信したり、データベース内の情報を更新したり、PHPのエコーを使ってレスポンスを返すことだって出来ます。
それでは今度は名前とメールアドレスを求めるようなシンプルなHTMLフォームがあったとします。以下にサンプルコードを記しますね。
HTMLとJavaScriptのページです。
<html> <head> <script type="text/javascript"> function updateProfile(){ // Let's first create our request object: var xmlhttp; if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); }else{ xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } // This code will be executed each time the readyState changes xmlhttp.onreadystatechange = function(){ if(ajaxRequest.readyState == 4){ document.getElementById("myData").innerHTML=xmlhttp.responseText; } } // We'll send any data to the server through our request object xmlhttp.open("GET","ourPHPCode.php",true); xmlhttp.send(); } </script> </head> <body> <form> <label>First Name;</label><br /> <input type='text' name='firstName' /> <label>First Name;</label><br /> <input type='text' name='lastName' /> <label>First Name;</label><br /> <input type='text' name='email' /> <input type=submit' onClick='updateProfile()' /> </form> <div id="myDate"></div> <!-- Our response will be placed into the div above, thanks to JavaScript's "innerHTML" property. --> </body> </html>
PHPスクリプトです。
<?php $firstName = $_POST['firstName']; $lastName = $_POST['lastName']; $email = $_POST['email']; $response = ''; // Now you have variables from the form, and you can do whatever with them: // validate them, update a database, insert them into a database, or whatever. // You can do whatever you'd normally do with regular PHP here. // You can then create a response variable, set it to whatever value you'd // like to send back to the user, and AJAX will update it automatically. // Examples: if(// Email isn't valid){ $response = "The email address you entered isn't valid."; } if(// Everything checks out ok and was submitted properly){ $response = "Your profile has been updated!"; } echo $response; ?>
このサンプルにはフォームデータを操作する方法が書いてあり、PHPを使ってサーバとやりとりするのと何ら変わりがないことが分かるかと思います。またデータベースへのリンクや、ページ内で取得した情報を使ってデータベースと通信させることも出来ます。HTMLフォームと同じようにAJAXもPOSTを使ってデータを送信することが出来ます。サーバサイドスクリプトの観点から言うと、全ておなじことです。
まとめ
AJAXはWebテクノロジーに革命を起こしました。必要に応じてクライアントサイドスクリプトがサーバのデータにアクセスすることが出来たり、それなのにクライアントサイドの利点であるスピードやユーザーフレンドリーさは更に進化しています。しばらく時間こそかかりましたが、今こうしてAJAXがコモンプラクティスとして脚光を浴びているのは、なんだかとっても嬉しいですね。
Web上にはチャットボックスやライブフィードを作ったり、動的な情報更新などAJAXに関するチュートリアルが無限と存在します。けれど、AJAXがどの様に動作するかという基礎の部分を理解する方がよっぽど大切です。AJAXを正しく理解すればこそ、様々な状況で最も効率的な方法で活用することが出来るのではないでしょうか。