WebOS Goodies

WebOS の未来を模索する、ゲームプログラマあがりの Web 開発者のブログ。

WebOS Goodies へようこそ! WebOS はインターネットの未来形。あらゆる Web サイトが繋がり、共有し、協力して創り上げる、ひとつの巨大な情報システムです。そこでは、あらゆる情報がネットワーク上に蓄積され、我々はいつでも、どこからでも、多彩なデバイスを使ってそれらにアクセスできます。 WebOS Goodies は、さまざまな情報提供やツール開発を通して、そんな世界の実現に少しでも貢献するべく活動していきます。
Subscribe  [Atom feed]  [Google]  [Bloglines]  [livedoor Reader]  [はてなRSS]  [Opera Widgetize]

XMLHttpRequest の使い方

今日は、JavaScript の XMLHttpRequest オブジェクトの使い方を調べてみたので、それをご紹介しようと思います。XMLHttpRequest はサーバーに対して HTTP リクエストを発行するためのオブジェクトで、AjaxA(Asynchronous) を司る中核技術です。これにより、Web ページを切り替えることなくサーバーからデータを取得し、ページ内容を更新することができます。

さあ、一緒に Ajax の世界へと足を踏み入れましょう!(^^)

使用方法


それでは、XMLHttpRequest オブジェクトの使用方法を順を追ってご紹介します。

XMLHttpRequest オブジェクトの作成


XMLHttpRequest オブジェクトを作成する方法は、Firefox, Opera と IE で異なります。Firefox, Opera の場合は単に XMLHttpRequestクラスのオブジェクトを作成するだけですが、IE6 は ActiveXObject として作成しなければなりません。実際のコードは以下のようになります。

httpRequest = false;
if(window.XMLHttpRequest) {
    // Firefox, Opera など
    httpRequest = new XMLHttpRequest();
    httpRequest.overrideMimeType('text/xml');
} else if(window.ActiveXObject) {
    // IE
    try {
        httpRequest = new ActiveXObject('Msxml2.XMLHTTP');
    } catch (e) {
        httpRequest = new ActiveXObject('Microsoft.XMLHTTP');
    }
}

httpRequest 変数をグローバル変数としていることに注意してください。これは、後述のコールバック関数で httpRequest にアクセスする必要があるからです。Firefox などのコードパスで指定されている overrideMimeType は、古い Mozilla ブラウザの制限への対処です。また、IE のコードパスでは、DLL のバージョンによって作成するオブジェクトを分けています。どちらもおまじないと考えておけば良いでしょう。

GET リクエストの発行


GET メソッドによるリクエストの発行は非常に簡単です。

httpRequest.open('GET', 'http://webos-goodies.jp', true);
httpRequest.onreadystatechange = processResult;
httpRequest.send(null);

open はリクエスト方法を指定するメソッドです。引数は順番に、HTTP のリクエストメソッドの指定、発行する URL、非同期リクエストを行うかどうかの bool 値(true なら非同期)です。リクエストメソッドは大文字小文字を区別しますので注意してください。onreadystatechange はレスポンスを処理するコールバック関数を指定するプロパティーです。send メソッドを呼び出すと実際にリクエストを発行します。引数としてリクエストボディーの文字列を指定しますが、ここでは必要ないので null を渡しています。

POST リクエストの発行


POST メソッドによるリクエストの発行はリクエストヘッダとリクエストボディーをきちんと指定しないといけないため、少々面倒です。コードはだいたい以下のようになります。

httpRequest.open('POST', 'http://webos-goodies.jp/', true);
httpRequest.onreadystatechange = processResult;
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.send('param1=value1¶m2=value2');

open, onreadystatechange は前述のとおりです。setRequestHeader はリクエストヘッダをカスタマイズする場合に使用します。ここでは "Content-Type: application/x-www-form-urlencoded"という行をヘッダに追加しています。そして、send メソッドの引数として QUERY_STRING を渡しています。ここにユーザー入力を含める場合は、URL エンコードを忘れないでください。

なお、ここではフォーム形式のデータを渡していますが、Content-Type を適切に設定すればそれ以外の形式のデータも渡すことが出来ます。

レスポンスの処理


サーバーからのレスポンスの処理は、onreadystatechange に指定したコールバック関数で行います。このコールバック関数は、通常以下のような実装になります。

function processResponse() {
    if(httpRequest.readyState == 4) {
        if(httpRequest.status == 200) {
            // リクエストの処理
        } else {
            // エラー処理
        }
    }
}

最初の if 文は読み込みが完了したかどうかを判定しています。readyState は現在の XMLHttpRequest オブジェクトの状態を示すプロパティーで、以下の値をとります。

readyState の値状況
0open が呼ばれる前
1open が呼ばれ、send が呼ばれるまで
2send が呼ばれ、レスポンスヘッダを受信した
3レスポンスのボディーを受信中
4すべてのデータの受信が完了した

2 番目の if 文は、レスポンスのステータスを判定しています。HTTP プロトコルの既定により、リクエストが正常に処理された場合にはステータスを 200 にして返答することになっていますので、それ以外はエラーとして扱っています。

実際のレスポンスデータは、XMLHttpRequest オブジェクトのプロパティーとして取得できます。主に参照されるプロパティーは以下のとおりです。

プロパティー保持しているデータ
responseTextボディーの文字列そのもの
responseXMLボディーを DOM Document オブジェクトとして解釈したもの
statusステータス現
statusTextステータス文字列

また、以下のメソッドでレスポンスヘッダを取得できます。

メソッド取得する情報
getAllResponseHeaders()レスポンスヘッダ全体を取得
getResponseHeader(header)header で指定したヘッダを取得

リクエストの中止


発行済みのリクエストを中止するには、abort メソッドを使用します。以下のように単純に呼び出せば OK です。

httpRequest.abort();

また、XMLHttpRequest オブジェクトを再利用する際も、abort メソッドを呼び出す必要があるようです。

制限


XMLHttpRequest は便利な機能ですが、セキュリティーの関係からそのページと同じドメインからしかドキュメントを取得できません。別ドメインの URL を指定すると、リクエストが発行されないようです。ローカルにある HTML ファイルからはいかなるドメインにもリクエストを投げられないので注意してください。

なお、Opera Widgets ならこの制限がかからないので、XMLHttpRequest を使ったページの作成環境としてけっこう便利に使えます。オススメです。

サンプル


解説だけではあれなので、簡単なサンプルを作ってみました。コンボボックスからページを選択すると、そのページのソースを表示します。 Livedoor blog は文字コードが EUC なので日本語は文字化けしてしまいますが( JavaScript はユニコードベースなのです)、ご了承ください。


ソースは以下のようになっています。

<script>
httpRequest = false;
if(window.XMLHttpRequest) {
    // Firefox, Opera など
    httpRequest = new XMLHttpRequest();
    httpRequest.overrideMimeType('text/xml');
} else if(window.ActiveXObject) {
    // IE
    try {
        httpRequest = new ActiveXObject('Msxml2.XMLHTTP');
    } catch (e) {
        httpRequest = new ActiveXObject('Microsoft.XMLHTTP');
    }
}

function request(page)
{
    if(page == '') return;
    httpRequest.abort();
    httpRequest.open('GET', 'http://webos-goodies.jp/archives/' + page + '.html', true);
    httpRequest.onreadystatechange = function() {
        if(httpRequest.readyState == 4) {
            if(httpRequest.status == 200) {
                document.getElementById('sw_text').value = httpRequest.responseText;
            }
        }
    }
    httpRequest.send(null);
}
</script>

<select onchange="request(this.value);">
<option value=""></option>
<option value="50067950">仮想マシンの作成</option>
<option value="50076580">インストール CD の起動</option>
<option value="50077769">HDD のフォーマット</option>
<option value="50078623">システムファイルのインストール</option>
<option value="50079003">Portage の環境設定</option>
<option value="50080053">カーネルコンパイル</option>
<option value="50089919">環境設定</option>
<option value="50098197">デーモン、ブートローダーのインストール</option>
<option value="50109765">ユーザーの追加</option>
<option value="50123244">VMwareTools のインストール</option>
</select>

<textarea id="sw_text" style="width: 100%; height: 200px;"></textarea>

XMLHttpRequest、使ってみるとけっこう簡単ですね。前から試したいと思いつつ漠然と面倒くさそうなイメージがあって敬遠していたのですが、こんなことなら早く調べておけばよかった(^^ヾ。使いようによっては、普通の Web ページでも面白いことが出来るかもしれませんね。

ただ、ドメインをまたげないという制限があるので、livedoor blog ではちょっと使いづらいかな・・・。なにか面白い活用方法はないものでしょうかね。
関連記事

トラックバックURL

※システムの都合によりトラックバックの受け付けは中止しております。

この記事にコメントする