その1
序章
sirmiles.comでは、「手抜きなショッピング・モール」というサイトを公開していました。Amazon、楽天、ビッダーズ、ストアミックスから、商品を一括検索するというページです。
ただし、このページは面白味がなく、アフィリエイトとしても殆ど役に立たなかったため、「もうちょっとこのページで遊べないか」と考えるようになりました。
月日は過ぎ、Google Mapを目にし、これがJavaScriptを基幹とした技術で作られているとは思いもしませんでした。
さらに月日は過ぎ、ふと「Ajax」という言葉を目にし、衝撃を受けました。これだ!(?)と直感した私は、本屋で羽田野太巳氏の著作「AJAX Webアプリケーションアイデアブック」をすぐに買って帰り、色々とサンプルスクリプトを作っては遊んでみました。
そして、Ajaxのクセを一通り頭に入れ、「手抜きなショッピング・モール」を「インタラクティヴ・プラザ」に改変すべく、作業を開始しました。
ソリューション
Ajaxはクライアントサイドとサーバーサイドの連携によって、ブラウザがサイト間を移動することなく、ユーザーアクションなどに応じてコンテンツを動的に変更する方法論です。
私は、1-man.netでサーバーレンタルしており、このサーバではPHP4が使える為、サーバーサイドはPHP4で構築します。
クライアントサイドのスクリプトは、羽田野太巳氏の著作を最大限に活用させていただきました。多謝。ブラウザは、Ajaxで使用する特定のオブジェクトが、JavaScriptにおいて使用できるものに一応限定します。
ただし、クローラー対策(リンク先になった場合に中身を拾ってもらう=アフィリエイトに有利になるようにする)として、メインページがGETパラメータを受け付けるようにし、通常のクエリ送信検索も可能とします。これにより、動作保障外ブラウザでも、一応検索ができるはずです。
流れとしては…。
ページの検索ワードに文字を入力すると、そのイベントを感知したJavaScriptのイベントハンドラが、XMLHttpRequestオブジェクトを使用してサーバーサイドのPHPスクリプトにリクエストを投げます。
サーバーサイドのPHPスクリプトは、各ショッピングモールのWebサービスにアクセスし、なるべく簡単なXMLドキュメントを生成してクライアントへレスポンスを返します。
レスポンスを受け取ったクライアントは、XMLを解析し、ページ内の適切なdivタグに対して、商品を羅列するHTMLを追加していきます。
こうして、検索ワードに応じた結果が、入力するたび(実際は負荷軽減のため、インターバルを取っていますが)に変化します。
index.php
まずは、実際のページです。「index.php」となっていますが、PHPスクリプトを説明すると、AJAXにたどり着かないので、ブラウザに帰ってきた基本的なHTMLで説明します。基幹的な部分以外は省略しています。文字セットはUTF-8とします。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ja"> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <title>インタラクティヴ・プラザ βver. Presented by SirMiles</title> <script type="text/javascript" src="ajax.js"></script> <script type="text/javascript" src="plaza.js"></script> </head> <body> <h1 id="top">Ajaxを利用して、Amazon・楽天・ビッダーズ・ストアミックスから、インタラクティヴに商品を検索します。</h1> <div id="msg" style="font-weight : bold; background-color : #CCFFFF; border : solid 1px #00CCCC; height : 1.5em;"></div> <form id="searchbox" action="index.php" method="get" target="_top" accept-charset="utf-8"> <p>検索ワード:<input id="Keywords" name="Keywords" type="text" size="50" value="" /><input id="submitbutton" type="submit" value="検索" /></p> <script type="text/javascript"> <!-- if(objValid()) { document.getElementById("submitbutton").disabled = true; } else { document.write('<p><strong>インタラクティヴ検索はご利用になれません。検索ボタンをご利用ください。</strong></p>'); } //--> </script> <noscript> <p><strong>インタラクティヴ検索はご利用になれません。検索ボタンをご利用ください。</strong></p> </noscript> <p><input type="radio" name="Sort" value="Bestselling" id="SortBestselling" checked="checked" /><label for="SortBestselling">指定なし</label> <input type="radio" name="Sort" value="Newest" id="SortNewest" /><label for="SortNewest">新着順</label> <input type="radio" name="Sort" value="LowPrice" id="SortLowPrice" /><label for="SortLowPrice">安い順</label> <input type="radio" name="Sort" value="HighPrice" id="SortHighPrice" /><label for="SortHighPrice">高い順</label></p> <p class="indent">※ アマゾンの場合、カテゴリー指定がないと、新着順や価格順が無効になります。</p> <p class="indent">※ ストアミックスの場合、カテゴリーや並び順はすべて無効になります。</p> <hr/> <table summary="CATEGORY" border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td> <p><input id="Amazon" name="Amazon" type="checkbox" checked="checked" value="true"/>アマゾン:</p> </td> <td> <p> <select id="SearchIndex" name="SearchIndex" style="width : 20em;"> <option value="Blended" selected="selected">カテゴリー指定なし</option> <option value="Books" >本</option> <option value="ForeignBooks" >洋書</option> <option value="Electronics" >エレクトロニクス</option> <option value="Kitchen" >キッチン</option> <option value="Music" >音楽</option> <option value="Classical" >クラシック</option> <option value="MusicTracks" >音楽トラック</option> <option value="DVD" >DVD</option> <option value="Video" >ビデオ</option> <option value="VHS" >VHS</option> <option value="Software" >ソフトウェア</option> <option value="VideoGames" >ゲーム</option> <option value="Toys" >トイ</option> </select> </p> </td> <td> <p> </p> </td> </tr> <tr> <td> <p><input id="Rakuten" name="Rakuten" type="checkbox" checked="checked" value="true"/>楽天:</p> </td> <td> <p> <select id="Genre" name="Genre" style="width : 20em;"> <option value="" selected="selected">カテゴリー指定なし</option> <option value="100371" >ファッション</option> <option value="100227" >グルメ(食品)</option> <option value="100316" >グルメ(ドリンク)</option> <option value="100553" >生活・インテリア</option> <option value="100026" >パソコン・家電・AV</option> <option value="100938" >ダイエット・健康</option> <option value="101070" >スポーツ・アウトドア</option> <option value="100939" >美容・コスメ・香水</option> <option value="101164" >おもちゃ・ホビー・ゲーム</option> <option value="101240" >CD・DVD・楽器</option> <option value="100005" >フラワー・ガーデン</option> <option value="101213" >ペット・ペットグッズ</option> <option value="101114" >車・バイク</option> <option value="100533" >キッズ・ベビー・マタニティ</option> <option value="200162" >本・雑誌・コミック</option> <option value="101381" >旅行・出張・チケット</option> <option value="200163" >不動産・住まい</option> <option value="101438" >サービス</option> </select> </p> </td> <td> <p> </p> </td> </tr> <tr> <td> <p><input id="Bidders" name="Bidders" type="checkbox" checked="checked" value="true"/>ビッダーズ:</p> </td> <td> <p> <select id="Categ" name="Categ" style="width : 20em;"> <option value="" selected="selected">カテゴリー指定なし</option> <option value="7" >コンピュータ</option> <option value="8" >家電・AV・カメラ</option> <option value="4" >ブランド</option> <option value="3" >ファッション</option> <option value="931" >ペット・いきもの</option> <option value="909" >グルメ・ドリンク</option> <option value="211" >チケット・金券</option> <option value="10" >キッズ・ベビー</option> <option value="921" >ヘルス・ビューティー</option> <option value="27" >アクセサリー・時計</option> <option value="6" >アンティーク・コレクション</option> <option value="28" >ホビー・カルチャー</option> <option value="5" >レジャー・スポーツ</option> <option value="508" >自転車・バイク</option> <option value="9" >住まい・インテリア・花</option> <option value="2" >音楽・映画・DVD</option> <option value="1019" >おもちゃ・ゲーム</option> <option value="1" >タレント・キャラクターグッズ</option> <option value="212" >本・雑誌・コミック</option> <option value="11" >ビジネス・事務・店舗用品・文房具</option> </select> </p> </td> <td> <p> </p> </td> </tr> <tr> <td> <p><input id="Storemix" name="Storemix" type="checkbox" checked="checked" value="true"/>ストアミックス:</p> </td> <td> <p> <select id="SCateg" name="SCateg" style="width : 20em;" disabled="disabled"> <option value="" selected="selected">カテゴリー指定なし</option> </select> </p> </td> </tr> </tbody> </table> </form> <hr /> <div id="amazonbookmarks"></div> <div id="rakutenbookmarks"></div> <div id="biddersbookmarks"></div> <div id="storemixbookmarks"></div> <div id="amazoninfo"></div> <div id="amazonresults"></div> <div id="amazonerror"></div> <div id="rakuteninfo"></div> <div id="rakutenresults"></div> <div id="rakutenerror"></div> <div id="biddersinfo"></div> <div id="biddersresults"></div> <div id="bidderserror"></div> <div id="storemixinfo"></div> <div id="storemixresults"></div> <div id="storemixerror"></div> </body> </html>
このHTMLの解説は次回。