XMLHttpRequest オブジェクトの利用方法
Web サービスが広く使われるようになり、不都合に感じてくるのがいちいちページを再ロードする必要があるということです。これらを解消することができないか?ということで最近注目されたのが XMLHttpRequest です。これはもともと Internet Explorer 5 の Active X のオブジェクトとしてインプリメントされました。それを Mozilla 1.0 や Safari 1.2 でも採用されることになりました。
オブジェクトの生成
まずは、オブジェクトを生成するところから始まります。オブジェクトは、Mozilla, Safari では XMLHttpRequest
を Internet Explorerでは XMLHTTP
をActiveX にて生成します。オブジェクトとを生成する関数を作成してみます。
// XMLHttpRequestオブジェクト生成 function createHttpRequest() { // for ie7, Mozilla, FireFox, Opera8 if (window.XMLHttpRequest) { try { return new XMLHttpRequest(); } catch (e) { return false; } } // for ie5, ie6 else if (window.ActiveXObject) { try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { return false; } } } else { return false; } }
メソッド
オブジェクトを生成した後は、メソッドを利用して必要なコントロールを行います。
メソッド | 概要 |
---|---|
abort() |
現在のリクエストを停止 |
getAllResponseHeaders() |
すべてのヘッダーを返す(ラベルと値) |
getResponseHeader("headerLabel") |
指定したヘッダーのラベルの値を返す |
open("method", "URL"[, asyncFlag[, "userName"[, "password"]]]) |
メソッドやURLなどを割り当てる。asyncFlag が true で非同期通信、falseで同期通信となる。 |
send(content) |
リクエストを送信。文字列や DOMオブジェクトを指定可能。 |
setRequestHeader("label", "value") |
ラベルと値でついになったヘッダーを送信。 |
open()
および send()
が最も利用するメソッドです。
まず、open()
によりサーバー側で実行されるプログラムの設定を行います。はじめの引数で、データをサーバーに渡す方法を指定します。URLを利用してデータを送る場合"GET"
を利用します。"GET"
は、簡単にデータをサーバーに送ることができますが、URIエンコードをしておく必要があることとサイズを全体で 512バイト以内に抑える必要があります。大きなデータを扱う場合には"POST"
を利用します。"POST"
は、FORMで 指定されたデータしか扱うことができません。2番目に引数である URL でサーバ側で実行されるプログラムを指定します。 3番目に引数は、通信を非同期で行うか同期で行うかを指定します。true
が非同期通信、false
が同期通信となります。 デフォルトは非同期通信です。非同期通信は、send()
メソッドが実行された後にサーバで実行されるプログラムのレスポンスを待たずに次の処理を続けます。サーバーで実行されたプログラムのレスポンスは onreadystatechange
イベントをチェックすることで処理します。
var objReq=false; // 送信関数 // @param callback 受信時に起動する関数名 // @param data 送信するデータ // @param method "POST" / "GET" // @param url 実行するプログラムのURL // @param async true:非同期 / false:同期 function sendRequest(data, method, url, async) { // XMLHttpRequestオブジェクト生成 objReq = createHttpRequest(); if (objReq == false) { return null; } objReq.onreadystatechange = procReqChange; if (method == 'GET') { url = url + encodeURI(data); } objReq.open(method, url, async); if (method == 'POST') { objReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); } objReq.send(data); }
プロパティ
リクエストを送ったあとは、いくつかのプロパティを監視することでサーバー側で実行されたプログラムのレスポンスを確認できます。
プロパティ | 概要 | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
onreadystatechange |
状態が変更された際のイベントハンドラを指定。 | ||||||||||||||||||||
readyState |
オブジェクトの状態:
|
||||||||||||||||||||
responseText |
サーバーから文字列形式のデータが返る。文字エンコーディングはブラウザによって異なる。 | ||||||||||||||||||||
responseXML |
サーバーからDOM形式のデータが返る。 | ||||||||||||||||||||
status |
サーバからの数値によるリターンコード。404 は "Not Found"、200 は "OK"。 | ||||||||||||||||||||
statusText |
サーバからの文字列によるリターンメッセージ。 |
readyState
プロパティを利用することでオブジェクトの状態を確認できる。サーバー側のプログラムが完了したことを表す値は 4
となります。また、サーバー側のプログラムがどのような状態で完了したかは status
プロパティを利用することで確認できます。HTTPなので、status
は 200
が成功となります。失敗していた場合、statusText
プロパティを利用してエラーの内容を確認できます。サーバーからのデータは、responseText
またはresponseXML
プロパティーを通して返ります。
// 受信時に起動するコールバック関数 function procReqChange() { // 状態 if (objReq.readyState == 4) { // ステータス if (objReq.status == 200) { // 成功! alert("受信しました: " + objReq.responseText); } else { // 何か不具合が発生? alert("問題が発生しました: " + objReq.statusText); } } }
サンプル
上記をふまえて簡単なプログラムを実行してみます。とても簡単なもので、ボタンを押すと1秒後にメッセージが切り替わるものです。
<html> <head> <title>XMLHttpRequest test</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script language="JavaScript"> <!-- // create XMLHttpRequest object function createHttpRequest() { // for ie7, Mozilla, FireFox, Opera8 if (window.XMLHttpRequest) { try { return new XMLHttpRequest(); } catch (e) { return false; } } // for ie5, ie6 else if (window.ActiveXObject) { try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { return false; } } } else { return false; } } var objReq; function sendRequest(data, method, url, async) { objReq = createHttpRequest(); if (objReq == false) { return null; } objReq.onreadystatechange = procReqChange; if (method == 'GET') { url = url + encodeURI(data); } objReq.open(method, url, async); if (method == 'POST') { objReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); } objReq.send(data); } function procReqChange() { if (objReq.readyState == 4) { if (objReq.status == 200) { var obj = document.getElementById("maintext"); obj.innerHTML = objReq.responseText; } else { alert("ERROR: " + objReq.statusText); } } } //--> </script> </head> <body> <form> <input type=button value="get message" onClick="sendRequest('', 'GET', 'mess.php', true); return false;"> </form> <div id="maintext">message here</div> </body> </html>
<?php sleep(1); echo 'hello, world!'; ?>
"get messgae"ボタンをクリックすると、1秒後にメッセージが変わります。
→ |
sendRequest
の4番目の引数を true
から false
に変更すると同期通信となります。どう違うかは実際に試してみるとわかります。