サーバー上の画像ファイルを読み込む

 今まではテキストファイル、HTMLファイル、XMLファイルを読み込んでみました。ここではテキストではなくバイナリデータや画像ファイルのデータを読み込んだら、どうなるのか実験してみましょう。
 画像を読み込んでresponseTextでページ上に表示できるでしょうか。以下がサンプルプログラムです。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>サーバー上の画像ファイルを読み込む</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadIMGFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
$("result").innerHTML = httpObj.responseText;
}else{
$("result").innerHTML = "<b>Loading...</b>";
}
}
// --></script>
</head>
<body>
<h1>サーバー上の画像ファイルを読み込む</h1>
<p>画像ファイルを読み込みます</p>
<form name="ajaxForm">
<input type="button" value="sample.gifファイルを読み込み" onClick="loadIMGFile('sample.gif')"><br>
<input type="button" value="sample.jpgファイルを読み込み" onClick="loadIMGFile('sample.jpg')"><br>
<input type="button" value="sample.pngファイルを読み込み" onClick="loadIMGFile('sample.png')"><br>
</form>
<div id="result"></div>
</body>
</html>

 結果はGIF形式であればGIF89a〜といった文字が表示されます。ただし、ブラウザによって表示される文字が異なります。JavaScriptではHTMLのimgタグのsrcプロパティにURLを指定することで画像を表示できますが、その代用にはならないようです。また、バイナリデータの場合、JavaScriptではバイト単位で処理できる命令がないため(*1) バイナリファイルの処理を行うことは現実的ではないでしょう。
 GIF形式の場合、先頭にはGIF87、GIF89aといった文字が書かれています。これにより拡張子がgifでなくてもファイルの先頭を読み出す事によって本物のGIF形式かどうかを調べることができます(このような先頭に書かれているデータ認識用コードはマジックコードと呼ばれます)。以下のサンプルはGIF、JPEG、PNG形式のデータを読み込んだ際に先頭のマジックコードを調べてGIF形式かどうか調べます。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>サーバー上の画像ファイルを読み込む2</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadIMGFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
imageData = httpObj.responseText;
ptr = imageData.indexOf("GIF89a");
if (ptr > -1)
{
$("result").innerHTML = "GIF89a形式です";
}else{
$("result").innerHTML = "GIF89a形式ではありません";
}
}else{
$("result").innerHTML = "<b>Loading...</b>";
}
}// --></script>
</head>
<body>
<h1>サーバー上の画像ファイルを読み込む2</h1>
<p>画像ファイルを読み込みます</p>
<form name="ajaxForm">
<input type="button" value="sample.gifファイルを読み込み" onClick="loadIMGFile('sample.gif')"><br>
<input type="button" value="sample.jpgファイルを読み込み" onClick="loadIMGFile('sample.jpg')"><br>
<input type="button" value="sample.pngファイルを読み込み" onClick="loadIMGFile('sample.png')"><br>
</form>
<div id="result"></div>
</body>
</html>

 バイナリーデータを処理したい場合にはサーバー側でテキスト(*2)にしてから送信し、JavaScriptで処理した後に再度サーバーに送信するのが妥当なところでしょう。

 せっかく画像を読み込むというネタなので、方向性を変えて役立ちそうなプログラムを作ってみましょう。例えば写真素材やカタログなどで画像の枚数が変わるとページを作り直したりすることがあります。これは画像の枚数が何枚なのかを最初に決定しておかないと(決まっていないと)ページを作る事ができないためです。画像が何枚あるのか不明な場合にはJavaScriptでサムネール画像を表示することができません(できるが画像が表示されない)。カタログなどはサーバー側でデータベースと連携して表示してしまいますが、せっかくのAjaxですからJavaScriptで画像が何枚あるのかを調べるプログラムを作りましょう。画像の枚数がJavaScriptで分かればサーバーに画像をアップするだけで済み、JavaScriptのコードを変更する必要がなくなります。コストも減りますし、サーバー側でデータベースやCGI, Perlが動作しなくても良いので、どんなサーバーでも大丈夫(サーバーを問わない)という大きなメリットがあります。
 サーバー上に画像が何枚あるかを調べるには、上記のスクリプトと同じように画像ファイルを取得します。この時にステータスコードが正常 (200) の場合には画像ファイルが存在することになります。画像が存在する場合には枚数を示すカウンタの値を1増やします。画像が存在しない場合 (404*3) には、これ以上画像は存在しないということになりますので後処理を行います。以下のサンプルでは単純に画像の枚数を表示しています。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>サーバー上の画像ファイルを読み込む3</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadIMGFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 404))
{
$("result").innerHTML = "画像の枚数は"+imageCount+"枚です";
}
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
imageCount++;
loadIMGFile(imageCount+".gif");

}
}
function loadStart()
{
imageCount = 0; // 読み込み画像ファイルの連番を入れる変数
loadIMGFile(imageCount+".gif");
}
// --></script>
</head>
<body>
<h1>サーバー上の画像ファイルを読み込む3</h1>
<p>連番GIF画像ファイルを読み込みます</p>
<form name="ajaxForm">
<input type="button" value="連番GIFファイルの数を調べる" onClick="loadStart()"><br>
</form>
<div id="result"></div>
</body>
</html>

 画像だけでなく特定のディレクトリにHTMLファイルがあるかどうかも同様の手法で調べることができます。このページのように連載形式のページには有益な方法かもしれません。サーバーにデータをアップロードするだけでプログラムコードは変更しなくて済むためです。このようにすることで、ようやく「データ」とプログラムを切り離すことができるようになります(今までのJavaScriptコードはデータの個数に大きく依存していました。このためサーバー側で処理することが多かったわけです)。

 ここまでで、基本的な部分の解説は終わりです。最低限の事しか記述していません。実際のプログラムでは、注意すべき点や障害がたくさんあります。次章からは実際のテキストデータ、XMLデータを使ってブラウザにデータ内容を表示してみます。これによりExcelのデータやFilemakerなどのデータベースのデータを活用することができるようになります。

*1 Netscapeブラウザのバージョン4.5以前であればcharAt()によってバイト単位の処理が一応可能でした
*2 例えばXBM, XPM形式にして処理する方法もあります。 *3 利用しているプロバイダやサーバーによってはリダイレクトのコード(300番台)を返す場合があります。

[第三章 1:タブ区切りテキストを表示するへ]
[目次へ]

(2005.12.31, 2006.8.18追記)