はじめに
ここ最近、Web 2.0という言葉と共にクライアント側のプレゼンテーション技術としてAjaxが非常に注目されています。しかし、Ajaxという技術用語や概念の解説、または書籍が多く出版されているにもかかわらず、Ajaxを応用したコンテンツやアプリケーションは、キーワードとしてのAjaxの人気から考えれば、少ないと言えるでしょう。多くの人がGoogleなどの大手サイトでAjaxを体験しているにもかかわらず、Ajaxが使われているのは企業や大手ポータルサイトなど、限定されています。
では、Ajaxはそれほど敷居の高いものなのでしょうか。質の高い開発集団や、高額な開発環境、またはサーバーなどのインフラストラクチャが必要となるのでしょうか。確かに、Googleと同じレベルのものを作ろうと考えれば、相応の費用と技術が要求されます。しかし、Ajaxという技術要素だけを見れば、けっして大企業に独占されるようなものではありません。CGIなどのサーバー側スクリプトやデータベースが使えないレンタルサーバーや、小さな自宅サーバーなどでも、魅力的なAjaxベースのコンテンツを作る方法があるはずです。
本稿では、こうした個人レベルのサイトでAjaxを応用する方法を、いくつか提案します。Blogなど、スクリプトやHTMLの記述に制約のあるシステムでは使うことができませんが、一般的なレンタルサーバーであれば本稿のサンプルを実行できるでしょう。
対象読者
Ajaxは、いくつかの標準的なWeb技術を組み合わせて実現するため、Ajaxを学習するにはAjaxを構成する個々の要素技術について、ある程度の経験が必要となります。
本稿では、Ajaxの柱となるいくつかの処理については解説しますが、古くから存在するHTMLやJavaScript、XML、DOM、HTTPプロトコルなどの標準技術については割愛させていただきます。そのため、少なくともHTMLとJavaScriptによる動的なWebページの製作を経験したことがある方を対象とさせていただきます。
また、本稿のサンプルはWindows XP上のMicrosoft Internet Explorer 7、およびMozilla Firefox 2で動作確認を行っています。
Ajaxの仕組み
まず最初に、Ajaxの基礎原理から改めて説明させていただきます。Ajaxはプログラミング言語やAPIのような明確な技術仕様や製品の名前ではなく、いくつかの技術の組み合わせで実現できる手法を表す抽象的な言葉です。DHTMLやWeb 2.0などと同様で、いくつかの技術を組み合わせた開発アプローチを指します。
Ajaxとは「Asynchronous JavaScript+XML」の省略で、JavaScriptコードから非同期にサーバーに問い合わせを行い、XMLデータ通信を行うことを意味します。技術的な原理としては、スクリプトの内部でサーバーに対してHTTPプロトコルを用いた要求を行い、結果をテキスト形式またはXML形式で受け、取得した情報を使ってページを更新します。この一連の作業をAjaxと呼びます。
まずは、Ajaxの最も基本的な作業である、JavaScriptからサーバーに通信する方法を見てみましょう。JavaScriptからサーバーに対して要求を行い、新しいコンテンツを取得するにはXMLHttpRequest
オブジェクトを使います。XMLHttpRequest
を利用するには、最初にnew演算子を用いてオブジェクトを生成しなければなりません。
var req = new XMLHttpRequest();
例えば、上記のようにXMLHttpRequest
オブジェクトを生成しreq
に代入すれば、req
をXMLHttpRequest
オブジェクトとして利用することができます。XMLHttpRequest
はWeb関連の標準技術を定めるW3Cによって草案が公開されています。草案にはIDLで書かれたXMLHttpRequest
インターフェイスの宣言も含まれ、これに準拠した実装であれば、異なるブラウザ間でも同じスクリプトが正しく動作します。詳細は、以下のURLを参照してください。
主要なブラウザは、細部での挙動に違いがあるもののXMLHttpRequest
の標準に従っています。そのため、ブラウザ専用のコードを書く必要はなく、同一のコードを異なるブラウザで実行することができます。本稿で紹介するXMLHttpRequest
オブジェクトのプロパティやメソッドは、W3Cが公開しているIDLに基づいたインターフェイスを抜粋したものです。
XMLHttpRequest
オブジェクトを生成したら、次は通信を行うためにopen()
メソッドを呼び出します。open()
メソッドは、要求を行うHTTPサーバーのURLと、HTTP要求メソッドを指定します。
void open(in DOMString method, in DOMString url); void open(in DOMString method, in DOMString url, in boolean async);
method
にはHTTP要求メソッドを、url
には取得したいコンテンツのURLを、それぞれ文字列で指定します。HTTP要求メソッドの詳細は割愛させていただきますが、データを取得することを目的とした要求にはGET
メソッドを用い、データを送信することを目的とした要求にはPOST
メソッドを使うのが一般的です。
本稿では、サーバー側のスクリプト処理を使わないAjaxの実用方法を考えることが目的なので、データをサーバーに送信して処理するということは行いません。そのため、本稿の範囲ではmethod
引数は常にGETを指定すると考えていただいてかまいません。
最後のasync
引数は省略可能で、データの送受信を非同期で行うかどうかを指定します。データの送受信が完全に終了するまでコードを待機させるにはasync
にfalseを指定しなければなりません。trueにした場合は、データを取得した時点で指定した関数を呼び出してもらう形になります。
open()
メソッドは接続先の設定を行うだけで、この時点ではサーバーに対する要求は行われていません。Webサーバーに要求するにはsend()
メソッドを呼び出します。
void send(in DOMString data);
data
には、サーバーに送信するデータを指定します。このデータはPOSTメソッドによる要求を行うときに使用します。サーバー側スクリプトなどでデータを受け取って処理をする場合に必要となりますが、この場では使わないのでnullとします。
open()
メソッドのasync
にfalseを設定している場合、通信は同期的に行われるため、サーバーからすべてのデータがダウンロードされるまでsend()
メソッドは制御を返しません。サーバーが応答しない場合などは、長時間、スクリプトが停止してしまう可能性があるので注意してください。
サーバーに要求したファイルのダウンロードが完了すれば、responseText
プロパティから文字列として取得することができます。
readonly attribute DOMString responseText;
要求したファイルがXMLファイルである場合、responseText
の代わりにresponseXML
プロパティを使ってDocument
オブジェクトを取得することができます。
readonly attribute Document responseXML;
これは、XMLHttpRequest
オブジェクトにXMLlという名前が付けられている所以です。本来、このオブジェクトはサーバーからのデータダウンロードを目的としたものではなく、XML文書の解析を行うコンポーネントでした。しかし、responseText
プロパティがあるように、現在ではXMLのためのコンポーネントとしてだけではなく、より汎用的なデータ取得用のオブジェクトとして利用することができます。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp"> <head> <title>test</title> <script type="text/javascript"> function requestText() { var req = new XMLHttpRequest(); req.open("GET", "test.txt", false); req.send(null); var pLabel = document.getElementById("label"); pLabel.innerHTML = req.responseText; } </script> </head> <body> <p id="label">ここに表示されます</p> <input type="button" value="ダウンロード" onclick="requestText()"/> </body> </html>
Kitty on your lap
sample00の「test.html」と「test.txt」を、HTTPサーバーの同じディレクトリ上にアップロードしてください。そして、ブラウザからアップロードした「test.html」にアクセスして表示してください。「ダウンロード」ボタンを押すと、labelという名前のp
タグの内容が「test.txt」の文字列に置き換わります。「test.txt」ファイルの内容は、任意に変更していただいてかまいません。
また、このこれらのファイルの文字コードをUTF-8で保存するように注意してください。Windows標準のShift-JISなどの場合、文字化けして正常に動作しないことがあります。
sample00は、[ダウンロード]ボタンを押すと、JavaScriptのrequestText()
関数を呼び出してXMLHttpRequest
オブジェクトを生成し、「test.txt」をダウンロードしています。 このダウンロードはブラウザのページ移動とは無関係に、スクリプトの内部だけで行われます。ダウンロードしたデータは、responseText
プロパティから文字列として受けとっています。
sample00は、XMLHttpRequest
に対応していないIE 7よりも前のバージョンのIEでは動作しません。IE 6までは、XMLHttpRequest
という名前ではなく、ActiveXObject
オブジェクトのMsxml2.XMLHTTPまたはMicrosoft.XMLHTTPという名前で生成していました。XMLHttpRequest
に直接対応したのはIE 7からです。これらは生成方法が違うだけで、基本的な使い方は同じです。
IE 7よりも古いバージョンに対応させるには、XMLHttpRequest
が存在するかどうかを調べ、存在しない場合はActiveXObject
オブジェクトを生成するように分岐させます。多くのAjax開発者は、次のようなコードを関数にまとめてオブジェクトを生成させています。
if ("XMLHttpRequest" in window) { req = new XMLHttpRequest(); } else if ("ActiveXObject" in window) { try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { req = null; } } } ...
これで、IE、Firefoxなどの主要なブラウザで共通して動作するスクリプトを書くことができます。