いろいろな人が所有している本(蔵書)の共有リストです。入力するコードはアマゾンで使われているASIN (ISBN) コードです。コードが入力されると自動的にアマゾンに問い合わせを行い関連情報をデータベースに登録します。このようなものを作成する場合にはSQLなどのデータベースがあると便利ですが、ここでは単純にクライアイント(ブラウザ)から送信されたテキスト情報をタブ区切りテキストとしてサーバーに保存しています。そして、サーバーに保存されたデータを一定時間ごとに読み出して情報を更新します。簡単に言えばチャットのような仕組みで動いています。(サンプルを
実行する)
アマゾンへの問い合わせ、該当書籍がある場合にはデータベースに登録という作業は、どちらかといえばサーバー側で行わせる方が無難です。が、ここではサーバー側のプログラムをシンプルな2つのCGIのみにして面倒な処理をブラウザ側で行わせています。特にこのような事をしなくても良いのですが、2つのCGIを組み合わせて(連携させて)利用するサンプルの1つとして見てもらえばよいかと思います。このため、コメントにどのような順番で処理が行われていくかを(〜)で示してあります。
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>蔵書共有 Ajax</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
registFlag = false; // 登録中かどうかのフラグ
// (1) ISBN検索
function amazonSearch()
{
registFlag = true;
$("registBtn").disabled = true;
var asin = $("ISBN").value;
httpObj = createXMLHttpRequest(registISBNData);
if (httpObj)
{
httpObj.open("GET","amazon.rb?asin="+asin+"&cache="+(new Date()).getTime(),true);
httpObj.send(null);
}
}
// (2) ISBNから本の情報を取得しデータベースに登録する
function registISBNData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200)) dataSave(getBookInfo(httpObj.responseXML));
}
// (2-2) 書籍情報を返す
function getBookInfo(xml)
{
if (xml.getElementsByTagName("Title").length > 0)
{
var TAB = String.fromCharCode(9);
var LF = String.fromCharCode(10);
uName = $("userName").value; // 登録者の名前
bookTitle = xml.getElementsByTagName("Title")[0].childNodes[0].nodeValue;
bookLink = xml.getElementsByTagName("DetailPageURL")[0].childNodes[0].nodeValue;
bookAuthor = xml.getElementsByTagName("Author")[0].childNodes[0].nodeValue;
bookPublisher = xml.getElementsByTagName("Publisher")[0].childNodes[0].nodeValue;
return uName+TAB+bookLink+TAB+ bookTitle + TAB+bookAuthor+TAB+bookPublisher+LF;
}else{
return null;
}
}
// (3) データベースに登録
function dataSave(registData)
{
if (!registData)
{
$("result").innerHTML = "<span style='color:red'>指定されたコードの書籍はアマゾンでは見つかりませんでした。</span>";
return;
}
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET","save.rb?request="+encodeURI(registData),true);
httpObj.send(null);
}
}
// (4) 登録完了メッセージ表示
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
$("result").innerHTML = "<span style='color:orange'>登録が完了しました</span>";
httpObj = createXMLHttpRequest(displayBookData);
if (httpObj)
{
msec = (new Date()).getTime();
httpObj.open("GET","bookdata.txt?"+msec,true);
httpObj.send(null);
}
registFlag = false;
$("registBtn").disabled = false;
}
}
// (5) 10秒に一回、リロードして最新蔵書データを読み込む
function dataReload()
{
if (!registFlag)
{
httpObj = createXMLHttpRequest(displayBookData);
if (httpObj)
{
msec = (new Date()).getTime();
httpObj.open("GET","bookdata.txt?"+msec,true);
httpObj.send(null);
}
}
setTimeout("dataReload()",1000*10);
}
// (6) 書籍情報表示
function displayBookData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
$("bookList").innerHTML = convBookData(httpObj.responseText);
}
}
// (7) 書籍データをHTMLデータに変換
function convBookData(bkList)
{
var resultHTML = "";
var TAB = String.fromCharCode(9);
var LF = String.fromCharCode(10);
bookData = bkList.split(LF);
for (var i=0; i<bookData.length; i++)
{
var txt = bookData[i].split(TAB);
uName = txt[0];
bookLink = txt[1];
bookTitle = txt[2];
bookAuthor = txt[3]
bookPublisher = txt[4];
if (bookAuthor == undefined) bookAuthor = "ー";
if (bookPublisher == undefined) bookPublisher = "ー";
if (bookTitle) resultHTML += '<span style="color:red">'+uName+'</span>の蔵書:<a href="'+bookLink+'">'+bookTitle+"</a> 著者:"+bookAuthor+" 出版社:"+bookPublisher+"<br>";
}
return resultHTML;
}
// --></script>
</head>
<body onload="dataReload()">
<h1>蔵書共有 Ajax</h1>
<p>最大50冊まで登録できます。アマゾンのASIN (ISBN) コードを入れてボタンを押すとデータベースに登録されます。</p>
<form method="get" name="ajaxForm" onsubmit="amazonSearch();return false;">
<input type="text" id="userName" value="ななしの権兵衛" size="16">
<input type="text" id="ISBN" value="4797332646" size="30"> <input type="submit" id="registBtn" value="データベースに登録"><br>
</form>
<div id="result"></div>
<div id="bookList"></div>
</body>
</html>
[
第12章 4:Yahoo JAPANランクインチェックへ]
[
目次へ]
(2006.2.6)