その3
ajax.js
次に、AJAX方法論の基礎部分を実現するJavaScriptファイルを見てみます。いきなり、全文を掲載。
羽田野太巳氏の著作「AJAX Webアプリケーションアイデアブック」を最大限に参考していますが、丸コピではなく、趣旨に合う様改変しています。羽田野太巳氏に謝辞の意を表します。
var httpObj = new Array(); var timerId = new Array(); // XMLHttpRequestオブジェクト作成 function makeXMLHttpRequest(name) { try { abortXMLHttpRequest(name); if(window.XMLHttpRequest) { // IE以外 httpObj[name] = new XMLHttpRequest(); } else if(window.ActiveXObject) { try{ // 最新IE httpObj[name] = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e2) { try{ // 旧IE httpObj[name] = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e3) { httpObj[name] = false; } } } else { httpObj[name] = false; } } catch(e1) { httpObj[name] = false; } // encodeURIComponentが使えるかどうか判断 if(window.encodeURIComponent) { ; } else { httpObj[name] = false; } } // XMLHttpRequestオブジェクトの通信中止 function abortXMLHttpRequest(name) { try { httpObj[name].abort(); } catch(e) { ; } } // 適格ブラウザ判断 function objValid() { makeXMLHttpRequest("dummy"); return httpObj["dummy"]; } // リクエスト送信 function httpRequest(target_url,post_data,funcitonReference) { message("検索中...しばらくお待ちください。"); makeXMLHttpRequest(target_url); if(!httpObj[target_url]) { // HTTPオブジェクト使用不能 httpObjGenerateFail('ご利用のブラウザでは、インタラクティヴ検索をご利用頂けません!'); } else { // タイマーセット if(timerId[target_url]) { clearInterval(timerId[target_url]); } timerId[target_url] = setTimeout('timeout("' + target_url + '")',30000); // オープン httpObj[target_url].open("POST",target_url,true); // ステータスチェンジイベントのハンドリング httpObj[target_url].onreadystatechange = function() { try { if(httpObj[target_url].readyState==4) { clearInterval(timerId[target_url]); if(httpObj[target_url].status==200) { funcitonReference(httpObj[target_url].responseXML); message(""); } else { return httpObjGenerateFail(httpObj[target_url].status + ' : ' + httpObj[target_url].statusText); } } } catch(e) { return httpObjGenerateFail(e.toString()); } } // リクエスト送信 httpObj[target_url].setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); httpObj[target_url].send(post_data); } } // メッセージ表示 function message(str) { document.getElementById('msg').innerHTML = str; } // XMLHttpRequestオブジェクト生成に失敗した場合の処理 function httpObjGenerateFail(str) { message(str); return false; } // タイムアウト処理 function timeout(target_url) { // タイマーをストップする clearInterval(timerId[target_url]); // HTTPリクエストを中断する abortXMLHttpRequest(target_url); // エラー表示 return httpObjGenerateFail('タイムアウトになりました。(' + target_url + ')'); } // イベントリスナ追加 function addListener(elem,eventType,func,cap) { if(elem.addEventListener) { elem.addEventListener(eventType, func, cap); } else if(elem.attachEvent) { elem.attachEvent('on' + eventType, func); } else { return httpObjGenerateFail('ご利用のブラウザでは、インタラクティヴ検索をご利用頂けません!'); } }
ajax.jsの解説
冒頭部分。
var httpObj = new Array(); var timerId = new Array();
httpObjは、XMLHttpRequestオブジェクトを格納する変数です。Array()で配列としているのは、Amazon、楽天、ビッダーズ、ストアミックスごとのリクエストを非同期で動かしたいからです。各ショッピングモールに対し、それぞれ固有のXMLHttpRequestオブジェクトがアクセスします。
timerIdは、XMLHttpRequestオブジェクトのタイムアウト処理をするために使います。setIntervalファンクションで得られるIDを格納します。これも、ショッピングモールごとに保持して各タイムアウトを非同期に処理します。
XMLHttpRequestオブジェクト作成ファンクション。
function makeXMLHttpRequest(name) { try { abortXMLHttpRequest(name); if(window.XMLHttpRequest) { // IE以外 httpObj[name] = new XMLHttpRequest(); } else if(window.ActiveXObject) { try{ // 最新IE httpObj[name] = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e2) { try{ // 旧IE httpObj[name] = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e3) { httpObj[name] = false; } } } else { httpObj[name] = false; } } catch(e1) { httpObj[name] = false; } // encodeURIComponentが使えるかどうか判断 if(window.encodeURIComponent) { ; } else { httpObj[name] = false; } }
本来は、ブラウザの判定をしてやるのが筋ですが、ここでは簡略化しています。
まず、abortXMLHttpRequestファンクション(後述)を呼び出して、当該XMLHttpRequestオブジェクトの通信を中止しておきます。
次に、XMLHttpRequestが使えるかどうか判断します。これにはFirefoxなどが対応しています。
ダメだった場合は、続いてActiveXObjectが使えるかどうか判断します。使える場合は、Msxml2.XMLHTTPのインスタンスを作成してみます。Msxml2.XMLHTTPが使えない場合は、Microsoft.XMLHTTPのインスタンスを作成します。
ActiveXObjectも使えない場合は、残念ながらAJAXの機能を放棄します。このとき、httpObj[name]には、falseを入れておきます。
最後に、encodeURIComponentが使えるかどうかを判断します。これは、JavaScriptからURLセーフな文字列を作成するために必要なので、これが使えない場合もAJAXの機能を放棄します。
XMLHttpRequestオブジェクトの通信中止ファンクション
function abortXMLHttpRequest(name) { try { httpObj[name].abort(); } catch(e) { ; } }
指定されたXMLHttpRequestオブジェクトの通信中止を試みます。
このファンクションが呼び出されたときに、当該XMLHttpRequestオブジェクトが通信中とは限らない上、そもそもインスタンスが存在するかどうかも不確定なので、try〜catchでエラートラップしておきます。
適格ブラウザ判断ファンクション。
function objValid() { makeXMLHttpRequest("dummy"); return httpObj["dummy"]; }
index.phpの中に登場したファンクションです。
makeXMLHttpRequestに"dummy"を渡して呼び出し、httpObj["dummy"]を作成します。このhttpObj["dummy"]の値がfalseの場合は、AJAXが使えないことになります。
そこで、httpObj["dummy"]がfalseでないときは、適格ブラウザだという結果(true扱いとなる)を返します。
次回は、ajax.jsの続きを解説します。