読者です 読者をやめる 読者になる 読者になる

imgタグのonerrorで処理すべきか?サーバ側でSocket通信で処理すべきか?

以下の要件があったとします

1.Aサーバに画像があればそれを表示(http://aサーバ/hoge.gif)
2.Bサーバを参照して画像があればそれを表示(http://bサーバ/hoge.gif)
3.Aサーバ・Bサーバに画像がなければlocalの[画像無し]という画像を表示(/img/noimage.gif)
 ※ここでlocalに画像が無いという事は考慮しない

つまり,AサーバにあればAサーバの画像を表示し,Aサーバに画像が無ければ次にBサーバを参照しBサーバに画像が存在した場合,Bサーバの画像を表示.
AサーバにもBサーバにもなければCサーバの[画像無し]という画像を表示するというもの.


imgタグonerrorイベントとは

<!-- hoge.gifがなければalert -->
<img src="hoge.gif" onerror="alert('読み込み失敗'); />

この画像の有無の要件をサーバ側のロジックで処理するとなると
テンプレート側に

<img src="ここが動的に変わるとこ"/>

サーバ側処理でSocket通信で有無を確認(例えばperlでAサーバのhoge.gifを確認する場合)

#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::INET;

my $sock;
$sock = IO::Socket::INET->new(PeerAddr => 'Aサーバ',
                              PeerPort => 'http(80)',
                              Proto    => 'tcp',
                              Timeout  => 2)
                          or die "connect failure\n";
print $sock "HEAD /hoge.gif HTTP/1.0\r\n";
my $res = <$sock>;
if($res =~ m/200 OK/){
  print "logo.gif exist\n";
}else{
  print $res;
}
close($sock);
1;

画像の有無をSocket通信で確認し,画像があればその画像のURLをテンプレート側の変数なるものに設定するでしょう.


同様の処理をサーバ側では無くクライアント側で処理するとなるとonerrorが利用出来ます.
# onerrorが再帰的に呼ばれる事を利用します.

<!-- Aサーバ固定を指定しておく -->
<img src="http://aサーバ/hoge.gif" onerror="test(this);"/>
function test(img){
  if(img.src.indexOf('aサーバ') != -1){
    img.src = 'http://bサーバ/hoge.gif';
  }else if(img.src.indexOf('bサーバ') != -1){
    img.src = '/img/noimage.gif';
  }else{
    // ここはありえない
  }
}

onerrorイベントが発生する毎に再帰的に
test関数が呼ばれ,最終的に存在する/img/noimage.gifが表示されます.


実際にかかるコストはどちらが上なのかというところですが知りたいですが
javascriptの記述をミスると無限ループに陥る可能性があるのと、
apackeのログが多く出力される事を考えると,無難にサーバ側で任せる方がいいのかな?