Json; JSON with Connection Manager
先の例では、YUIのConnection ManagerとXMLを使って、XHR(XMLHttpRequest)のサンプリングを行った。
RESTでマッシュアップをする(より広義には、Ajaxを実装する)際に、XMLだけでなく、JSONを外すわけにはいかない。(JSONについては、Wikipwdia:JSONを参照のこと)
YAMLから派生した、ハッシュ(辞書)形式のJSONは、Javascriptとの相性の良さから、UIとサーバープログラムとの分離といった、アプリケーション・アーキテクチャを考える上でも重要である。
サンプリングは、YUIのExampleをベースにした。YUIのExampleは、(Exampleのサーバー上にある)PHPプログラムの呼び出しを行っている。
開発機にあるApacheからレスポンスされるサンプルについては、クロスサイトスクリプティングを防止するという意味で、same oringin policy(スクリプトがアクセスできるサーバーは、それをレスポンスしたサーバーのみである)が適用されるために、このPHPプログラムを、サンプルのJavascriptから呼ぶことはできない。
先の(天気予報の)例のように、一度、サーバープログラムをProxyとして使う所以は、ここにある。
YUIのExampleには、幸い、以下のようなデータが示されているので、それを(サンプルのhtmlがあるディレクトリにdataディレクトリを作り)、ajax_json.txt(エンコーディングはUTF-8)として保存して、これを取得してみた。
[
{ "animal" : "Cat", "message" : "Meow" },
{ "animal" : "Dog", "message" : "Woof" },
{ "animal" : "Cow", "message" : "Moo" },
{ "animal" : "Duck", "message" : "Quack" },
{ "animal" : "Lion", "message" : "Roar" }
]
初期の画面は、以下。
ここで、「メッセージの取得」ボタンを押すと、このajax_json.txtを(XHRで)取得して、以下の画面を表示する。
以下に、Javascriptを含む、htmlの全文を示す。javascript内でevalをしないというのも、YUIに共通した(セキュリティー上重要な)特徴である。
<HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=UTF-8"> <META http-equiv="Content-Style-Type" content="text/css"> <TITLE>Ajax_Sampling</TITLE> <style type="text/css"> body { margin:0; padding:0; } #demo { width: 200px; hight: auto; padding: 10px; background-color: #6D739A; color: white; border: 1px solid green; } /*処理待ち画像*/ #wait { width: 18px; height: 18px; } </style> <!-- 読み込むjs --> <script type="text/javascript" src="scripts/yui/yahoo/yahoo-min.js" > </script> <script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js" > </script> <script type="text/javascript" src="scripts/yui/connection/connection-min.js" > </script> <script type="text/javascript" src="scripts/yui/json/json-min.js" > </script> <script type="text/javascript"> // namespaceの定義 YAHOO.namespace('EGP'); var ajaxHandlers=YAHOO.EGP.ajaxHandlers; var ajaxCallback=YAHOO.EGP.ajaxCallback; var btnHandlers=YAHOO.EGP.btnHandlers; // bottunクリックに処理を仕掛ける。 YAHOO.util.Event.on('demo_btn','click',function (e) { // demo_msgのdivにAliasをつける。見通しが悪い感じがしないかな。 var msg_section = YAHOO.util.Dom.get('demo_msg'); msg_section.innerHTML = ''; // Define the callbacks for the asyncRequest var callbacks = { success : function (o) { YAHOO.util.Dom.get('wait').innerHTML=''; var messages = []; try { // Jsonデータをパースする。パースできないとexceptionがでる。 // (注※) // [ // { "animal" : "Cat", "message" : "Meow" }, // { "animal" : "Dog", "message" : "Woof" }, // { "animal" : "Cow", "message" : "Moo" }, // { "animal" : "Duck", "message" : "Quack" }, // { "animal" : "Lion", "message" : "Roar" } // ] // は、プロパティー:animal, messageを持つオブジェクトの配列 // に変換される。evalは不要。 messages = YAHOO.lang.JSON.parse(o.responseText); } catch (x) { alert("JSON Parse failed!"); return; } // The returned data was parsed into an array of objects. // Add a P element for each received message // (注※)に示したオブジェクト配列より、htmlを形成する。 for (var i = 0, len = messages.length; i < len; ++i) { // オブジェクトの取得 var m = messages[i]; // pタグで段落を作る。 var p = document.createElement('p'); // オブジェクト.プロパティーで情報を取得し、TextNodeを形成する。 var message_text = document.createTextNode( m.animal + ' says "' + m.message + '"'); // 上で形成したTextNodeを、その上で作った段落(pタグ)につける。 p.appendChild(message_text); // msg_sectionは、demo_msgのAlias msg_section.appendChild(p); } }, failure : function (o) { YAHOO.util.Dom.get('wait').innerHTML=''; // HXRプロセスが生きているかどうか確かめる。 if (!YAHOO.util.Connect.isCallInProgress(o)) { alert("Async call failed!"); } }, // 5秒待って帰ってこなかったら、Timeoutし、callbacks.failureへいく。 timeout : 5000 } // JSONデータをレスポンスするPHPプログラムを呼ぶ。 YAHOO.util.Connect.asyncRequest('GET', "data/ajax_json.txt", callbacks); // wait画像(処理待ち画像)の表示 YAHOO.util.Dom.get('wait').innerHTML= "<img src='./images/wait.gif'/>"; }); </script> </HEAD> <BODY> <div id="demo"> <!-- 処理待ち画像 --> <div id='wait'></div> <input type="button" id="demo_btn" value="メッセージの取得"> <div id="demo_msg"></div> </div> </BODY> </HTML>