[[技術情報]] > Ajax * Ajax [#w8e287e7] #contents ** Ajaxとは? [#rbeb0121] 「Asynchronous JavaScript + XML」の略。 JavaScript(XMLHttpRequest)を用いて、Webサーバとの通信を非同期に行う技術。 ** メリットは? [#hd69b53a] Webアプリケーションでの画面遷移、操作性等の煩わしいさを改善することが可能となり、ユーザにとって使いやすく、クライアントアプリケーションに劣らないWebアプリケーションを実現することができる。 ** 非同期通信の方法 [#vd65af25] 以下の4つのステップで非同期通信を行う。 + 通信用クラスを生成する var req = null; if(window.XMLHttpRequest) { req = new XMLHttpRequest(); // Mozilla, Firefox, Safari, IE7 } else if(window.ActiveXObject) { // IE5, IE6 try { req = new ActiveXObject("Msxml2.XMLHTTP"); // MSXML3 } catch(e) { req = new ActiveXObject("Microsoft.XMLHTTP"); // MSXML2まで } } + サーバ接続のための情報をセットする req.open("GET", "リクエストするURL", true); ::openメソッド - サーバ接続のための情報をセットする| 引数 --- 第1引数:送信方式(GET方式:GET POST方式:POST) --- 第2引数:リクエストするURL --- 第3引数:非同期通信フラグ(true:非同期通信[Ajax] false:同期通信[Sjax]) + 通信状態が変化した時に発生するイベントのコールバック関数を定義する req.onreadystatechange = function() { if (// レスポンス受信完了 req.readyState == 4 // 正常終了 && req.status == 200) { // ====================================== // // レスポンス受信完了後の処理をここに記述 // // ====================================== } } ::onreadystatechangeイベント - 送受信状態が変った時に起動するイベント| イベント発生時のコールバック関数指定する。 この関数の中で「レスポンス受信完了」でかつ「正常終了」の場合に、レスポンス受信完了後の処理を記述する。 ::readyStateプロパティ - 通信状況を保持する| 値 --- 0:openメソッドが呼び出されていない --- 1:openメソッドが呼び出され、sendメソッドが呼び出されていない --- 2:レスポンスが来ていない --- 3:レスポンス受信中 --- 4:レスポンス受信完了 ::statusプロパティ - HTTPステータス・コードを保持する| 値(一部) --- 200:OK(正常終了) --- 404:Not Found(ファイルが見つからない) --- 403:Forbidden(アクセス拒否) --- 500:サーバ側の内部エラー + サーバにリクエストを送信する req.send(""); ::sendメソッド - サーバにリクエストを送信する| リクエスト方式を「POST」にした場合は、引数にパラメータを渡す。 パラメータ例:id=test&action=update&name=ken 引数 --- 第1引数:POSTのリクエストの場合、パラメータ. ** レスポンスデータの取得方法 [#wcf5e55d] レスポンスデータの取得方法は2通りある. + テキストとして取得する req.responseText ::responseTextプロパティ - サーバの応答をテキスト文字列として返す| + XMLDocument オブジェクトとして取得する req.responseXML ::responseXMLプロパティ - サーバの応答をXMLDocument オブジェクトとして返す| ** サンプル [#h1ea1bb3] *** もっともシンプルなAjax通信 - Hello Ajax!! [#x7723a69] クライアント側でのアクションによりAjaxでリクエストが送信され、サーバで返された文字列を表示する。 [[サンプルの実行 サンプルファイルダウンロードもこちら>http://www.trance.co.jp//technology/sample/ajax/hello/hello.html]] - ''ソース'' »'''HTML - hello.html''' <!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="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"> <title>もっともシンプルなAjax通信 - 株式会社トランスアーツ</title> <script language="JavaScript" type="text/javascript" src="./hello.js"></script> </head> <body> <h1>もっともシンプルなAjax通信 - Hello Ajax!!</h1> <p onclick="hello()">ここをクリックすると</p> <p id="message">ここにメッセージが表示されます</p> </body> </html> &br;»'''JavaScript - hello.js''' function hello() { // 通信用クラスを生成する var req = null; if(window.XMLHttpRequest) { req = new XMLHttpRequest(); // Mozilla, Firefox, Safari, IE7 } else if(window.ActiveXObject) { // IE5, IE6 try { req = new ActiveXObject("Msxml2.XMLHTTP"); // MSXML3 } catch(e) { req = new ActiveXObject("Microsoft.XMLHTTP"); // MSXML2まで } } // サーバ接続のための情報をセットする req.open("GET", "hello.php", true); // 通信状態が変化した時に発生するイベントを定義する req.onreadystatechange = function() { if (req.readyState == 4 && req.status == 200) { // ID属性が「message」のタグにレスポンスデータをセットする document.getElementById('message').innerHTML = req.responseText; } } // サーバにリクエストを送信する req.send(""); } &br;»'''サーバサイド(PHP) - hello.php''' <?php header( "Content-Type: text/html; charset=EUC-JP"); // クライアントに返す値 echo "Hello Ajax!!"; ?> &br; - ''解説'' »'''HTML - hello.html''' <p onclick="hello()">ここをクリックすると</p> 「ここをクリックすると」文字列をクリックした際に、Ajax通信するJavaScript関数「hello()」を設定&br;&br; <p id="message">ここにメッセージが表示されます</p> レスポンスデータを表示するためのタグにid属性値「message」を設定 &br;&br;»'''JavaScript - hello.js''' // サーバ接続のための情報をセットする req.open("GET", "hello.php", true); リクエストURLにサーバで実行するスクリプト「hello.php」を設定&br;&br; // 通信状態が変化した時に発生するイベントを定義する req.onreadystatechange = function() { if (req.readyState == 4 && req.status == 200) { // ID属性が「message」のタグにレスポンスデータをセットする document.getElementById('message').innerHTML = req.responseText; } } ID属性が「message」のタグにレスポンスデータをセット &br;&br;»'''サーバサイド(PHP) - hello.php''' header( "Content-Type: text/html; charset=EUC-JP"); // クライアントに返す値 echo "Hello Ajax!!"; クライアントに「Hello Ajax!!」返す。 &color(red){※注意}; 文字コードをクライアント、サーバ間で文字コードを合わせること。 *** もっともシンプルなAjax通信2 - パラメータ送信 [#ye9c47a0] クライアント側でのアクションによりAjaxでリクエストパラメータが送信され、サーバでリクエストパラメータの値を元に返された文字列を表示する。 [[サンプルの実行 サンプルファイルダウンロードもこちら>http://www.trance.co.jp//technology/sample/ajax/hello2/hello.html]] - ''ソース'' »'''HTML - hello.html''' <!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="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"> <title>もっともシンプルなAjax通信 - 株式会社トランスアーツ</title> <script language="JavaScript" type="text/javascript" src="./hello.js"></script> </head> <body> <h1>もっともシンプルなAjax通信 - Hello Ajax!!</h1> <p>言語を選択すると</p> <form name="helloForm"> <input type="radio" name="lang" value="ja" onclick="hello()">日本語 <input type="radio" name="lang" value="en" onclick="hello()">英語 </form> <p id="message">ここにメッセージが表示されます</p> <hr> <h2>サンプルコードファイルダウンロード</h2> <ul> <li><a href="./hello.html">HTML - hello.html</a></li> <li><a href="./hello.js">JavaScript - hello.js</a></li> <li><a href="./hello.php">サーバ側PHP - hello.php</a></li> </ul> </body> </html> &br;»'''JavaScript - hello.js''' function hello() { // 通信用クラスを生成する var req = null; if(window.XMLHttpRequest) { req = new XMLHttpRequest(); // Mozilla, Firefox, Safari, IE7 } else if(window.ActiveXObject) { // IE5, IE6 try { req = new ActiveXObject("Msxml2.XMLHTTP"); // MSXML3 } catch(e) { req = new ActiveXObject("Microsoft.XMLHTTP"); // MSXML2まで } } // サーバ接続のための情報をセットする var lang = getRadioValue(document.helloForm.lang); var reqParam = '?lang=' + lang; req.open("GET", "hello.php" + reqParam, true); // 通信状態が変化した時に発生するイベントを定義する req.onreadystatechange = function() { if (req.readyState == 4 && req.status == 200) { // ID属性が「message」のタグにレスポンスデータをセットする document.getElementById('message').innerHTML = req.responseText; } } // サーバにリクエストを送信する req.send(""); } /** * 選択されているラジオボタンの値を取得する. * @param {Object} radioButton */ function getRadioValue(radioButton) { var radioNum = radioButton.length; for (var i = 0; i < radioNum; i++) { if (radioButton[i].checked) { return radioButton[i].value; } } return ""; } &br;»'''サーバサイド(PHP) - hello.php''' <?php $lang = $_GET['lang']; $message = null; if ("ja" == $lang) { $message = "こんにちは、Ajax"; } else if ("en" == $lang){ $message = "Hello Ajax!!"; } else { $message = "言語を選択してください"; } header( "Content-Type: text/html; charset=EUC-JP"); echo $message; ?> - ''解説'' »'''HTML - hello.html''' <form name="helloForm"> <input type="radio" name="lang" value="ja" onclick="hello()">日本語 <input type="radio" name="lang" value="en" onclick="hello()">英語 </form> 言語を選択した際に、Ajax通信する「hello()」を設定 &br;&br;»'''JavaScript - hello.js''' // サーバ接続のための情報をセットする var lang = getRadioValue(document.helloForm.lang); var reqParam = '?lang=' + lang; req.open("GET", "hello.php" + reqParam, true); ラジオボタンで選択された値をリクエストパラメータとして ?パラメータ変数=パラメータ値&パラメータ変数=パラメータ値 の形式でopenメソッドの第2引数に渡す /** * 選択されているラジオボタンの値を取得する. * @param {Object} radioButton */ function getRadioValue(radioButton) { var radioNum = radioButton.length; for (var i = 0; i < radioNum; i++) { if (radioButton[i].checked) { return radioButton[i].value; } } return ""; } ラジオボタンは document.helloForm.lang.value では、選択された値が取れない。 ラジオボタンが選択されているか順番に確認する必要がある。 &br;&br;»'''サーバサイド(PHP) - hello.php''' $lang = $_GET['lang']; GET送信されたリクエストパラメータ「lang」の値を取得 if ("ja" == $lang) { $message = "こんにちは、Ajax"; } else if ("en" == $lang){ $message = "Hello Ajax!!"; } else { $message = "言語を選択してください"; } ラジオボタンで選択された言語によって返す値を設定 *** もっともシンプルなAjax通信3 - 共通関数化、レスポンスデータ処理外部関数化 [#a501b78c] 現状のhello()関数のAjax通信では、レスポンスデータの処理も一緒に実装されてしまっているため、共通で通信機能を使用することができない。 そこで、Ajax通信処理を共通的に使用できるようにし、レスポンスデータ処理を共通関数呼び出し元で個別で定義できるようにhello()関数を改良する。 [[サンプルの実行 サンプルファイルダウンロードもこちら>http://www.trance.co.jp//technology/sample/ajax/hello3/hello.html]] + 通信用クラスを生成する処理を関数化する。 /** * XMLHttpRequestを生成する. */ function createXMLHttpRequest() { if(window.XMLHttpRequest) { return new XMLHttpRequest(); // Mozilla, Firefox, Safari, IE7 } else if(window.ActiveXObject) { // IE5, IE6 try { return new ActiveXObject("Msxml2.XMLHTTP"); // MSXML3 } catch(e) { return new ActiveXObject("Microsoft.XMLHTTP"); // MSXML2まで } } } + サーバに通信部分のみの関数を作成する。 ここで第3引数にレスポンスデータの処理関数を受け取るようにする。 このレスポンスデータの処理関数はユーザ独自に設定する。 /** * サーバにリクエストを送信する. * @param url リスエスとするURL. * @param isAsync 非同期であるか.(true:Ajax false:Sjax) * @param execute サーバからレスポンスが来た際に実行する関数. */ function doGetRequest(url, isAsync, execute) { var req = createXMLHttpRequest(); req.open("GET", url, isAsync); req.send(""); req.onreadystatechange = function() { if (req.readyState == 4 && req.status == 200) { execute(req); } } } 使用方法 改良版hello.js function hello() { // レスポンスデータの処理関数を定義する var execute = function (req) { // ID属性が「message」のタグにレスポンスデータをセットする document.getElementById('message').innerHTML = req.responseText; } // リクエストを送信する // レスポンスデータの処理関数を渡す doGetRequest('hello.php', true, execute); } ** Ajax JavaScriptライブラリ [#c0e0fa51] - prototype.js http://www.prototypejs.org/ - YahooUI http://developer.yahoo.com/yui/index.html ** AjaxとWebAPI [#b8e61484] - Google Maps API - Amazon Webサービス - SimpleAPI[最寄り駅Webサービス]