2つ前の記事『Opera9.5正式版で気になった点(不具合や変更点)を挙げてみる』で、Opera9.5では"imgのsrcで画像ファイル以外を指定できなくなった"という指摘をしましたが、実際のところどうなのかを確かめてみました。
ことの発端ははてなブックマークの登録人数を表示するための画像ファイルがOpera9.5にアップデートしてから表示されなくなった、という発見。しかしいろいろと試してみると、表示されるときと表示されないときが不規則的にあることが判明(更新ボタンを押すたびに変わる)。そして表示されやすい画像と表示されにくい画像があることも発覚。バラつきの規則性がまったくわからないため、とりあえず実験してみるしかないじゃないか、ということでこのページに至ります。
先に書いてしまうと、“画像ファイルかどうかは関係なく画像が表示されないことがある”という実験結果を得ることができました。僕はてっきりimgのsrcが静的なURLだと読み込めなくなったのかと考えていましたが、URLと非表示の間には関係がなかったようです。ただ今回それ以上に重大なことがわかりました。それは……"そもそもブラウザとは関係なくプログラム経由で画像を呼び出すと表示されないことが多い"ということ……!!!!
使用した検証用のプログラムと結果、考察を以下に。
以下11コある画像(画像番号[1]-[11])は、すべてwww.dabun-doumei.comに設置したプログラム『20080621_Opera950ImageTest.php』で呼び出された画像です。引数を変えたURL(呼び出す方法が異なる)をそれぞれimgタグのsrcプロパティに指定しています。なお画像番号[1]~[6]はプログラムと同じサイト(同じドメイン)の画像、画像番号[7]~[11]は異なるサイト(異なるドメイン)の画像を読み込んでいます。
ちなみにこのきしめんロゴの画像についてはこの記事やこの記事を参照のこと。
さて、それでは検証用の画像ファイルを貼り付けていきます。
[1]-[6] :: www.trash-news.netというドメインからwww.dabun-doumei.comにあるプログラムを指定し、www.dabun-doumei.comにある画像を表示させる。
[1]はPHPのreadfile関数で読み込んだもの。[2]はPHPのheader関数(のLocation)で307 Temporary Redirect転送させて読み込んだもの。[3]はPHPのheader関数(のLocation)で301 Moved Permanently転送させて読み込んだもの。
[4]はPHPのheader関数で画像用のヘッダをつけたのち、PHPのreadfile関数で読み込んだもの。[5]はPHPのheader関数で画像用のヘッダ(Content-Disposition含)をつけたのち、PHPのreadfile関数で読み込んだもの。[6]はじかに画像を読み込んだもの(画像のURLを直接指定)。
以上、プログラムと画像が同じドメインにある環境でのテスト(はてブと同じ状態)でした。以下、プログラムとサーバーが違うドメインにある環境でのテストも念のため。
[7]-[11] :: www.trash-news.netというドメインからwww.dabun-doumei.comにあるプログラムを指定し、images.sakura.ne.jpにある画像を表示させる。
[7]はPHPのreadfile関数で読み込んだもの。[8]はPHPのheader関数(のLocation)で307 Temporary Redirect転送させて読み込んだもの。[9]はPHPのheader関数(のLocation)で301 Moved Permanently転送させて読み込んだもの。
[10]はPHPのheader関数で画像用のヘッダをつけたのち、PHPのreadfile関数で読み込んだもの。[11]はPHPのheader関数で画像用のヘッダ(Content-Disposition含)をつけたのち、PHPのreadfile関数で読み込んだもの。
なおwww.dabun-doumei.comに設置した画像読み込み用プログラム(20080621_Opera950ImageTest.php)のソースコードは以下の通り。
$SameSiteSRC = '../image/event/20080621_Opera950ImageTest.png';
$CrossSiteSRC = 'http://images.sakura.ne.jp/20080621_Opera950ImageTest.png';
if(isset($_GET['Mode'])){
$Mode = $_GET['Mode'];
if(isset($_GET['Ext'])){
header('Content-length: 6280');
header('Content-type: image/png');
if(isset($_GET['Att'])){
header('Content-Disposition: attachment; filename="TRASH-NEWS.png"');
}
}
switch($Mode){
case 'SameSiteRead' :
readfile($SameSiteSRC);
break;
case 'SameSiteTempRedirect' :
header("Location:{$SameSiteSRC}",TRUE,307);
break;
case 'SameSitePermaRedirect' :
header("Location:{$SameSiteSRC}",TRUE,301);
break;
case 'CrossSiteRead' :
readfile($CrossSiteSRC);
break;
case 'CrossSiteTempRedirect' :
header("Location:{$CrossSiteSRC}",TRUE,307);
break;
case 'CrossSitePermaRedirect' :
header("Location:{$CrossSiteSRC}",TRUE,301);
break;
default :
break;
}
exit();
}else{
readfile($SameSiteSRC);
exit();
}
なお同じドメインから同じドメインにあるプログラムを指定し~ということが検証できるように、www.dabun-doumei.comでも同じ検証用ページを設けています。
このプログラムではさまざまな方法で画像を読み込んでいます。[1]から[6]はいずれも過程は違えど読み込んでいるのは同じ画像ファイルなのです。[1]から[6]の中でもっともポピュラーな呼び出し方は[4]だと思われます。ヘッダは画像用のものをきちんと送出し、画像はreadfileで呼び出す。典型的と呼べる手順なのではないでしょうか。次いで[3](リダイレクト)、[1]([4]のヘッダ指定忘れ版)あたりが実用的といったところ。[2](一時的なリダイレクト)と[5](ダウンロード用ダイアログ表示)は特殊な書き方なのでまず見ないとは思いますが、念のため。[6]は処理は[1]とまったく同じですが、静的ページっぽいURLか否かで差異が出るかどうかを検証するため設けました。
[7]から[11]はそれぞれimages.sakura.ne.jpという、大昔に取得したサーバーに置いた画像を呼び出しているだけで、処理自体は同様です(それぞれ[1]から[5]に対応しています)。異なるドメイン・サーバーの画像を呼び出すと変わるのかどうかを検証するため設けました。
[1]-[11]、すべての画像が毎回表示されることを期待して、検証を始めました。理論的には毎回表示されてしかるべきです。
リロードを繰り返した回数 : 100回(Opera9.5/IE7/Firefox3それぞれにて)。
すべての画像が表示された回数 : 0回。
オオオオオ……。
実際にこのページ(か先述のこのページ)をリロードしていただければ一目瞭然ですが、かならずどれか1つは表示されない画像があるはずです。しかも毎回表示されない画像が異なるという……意味のわからない結果に(はてブ画像の問題と同じ結果ではある)! 1回表示したらキャッシュとして残るから安泰(?)だろうと思いきや、リロード後には非表示ということもしばしば。キャッシュの存在意義は?
そしてこのテスト結果はOpera9.5に限らずIE7でもほぼ同様のものが出ました。唯一Firefox3が"大体どの画像も90%以上の確率で表示される"という程度でしたが、すべての画像が表示された回数は100回中1回もありませんでした。……ハハハ。
PHPなどのプログラムで画像を表示させるというのは非常にありふれたことであり、僕自身何度も作成・設置してきました。が、まさかここまで表示されないことが多いとは思いもしませんでした。今回作ったプログラムにどこか穴があるのではと勘ぐりたくなるくらい……いや実際どう考えてもおかしい結果なので勘ぐっているのですが、とにかくそのくらい予想外の結果が出てしまいました。
以下気づいた点を列挙。
きちんと各ブラウザごとに回数を見たほうが良いんでしょうけれど、面倒かつ回数を厳密に見なくても"ヤバい結果"ということがわかっているので、感覚論で語ってみました。
ブラウザの設定によるものかと思いましたが、Operaの『ページの更新をサーバーに確認するタイミング』などを変えて試してみても結果は変わらず。まぁブラウザごと(Opera9.5+IE7 / Firefox3)で明らかな差が出ているということは、どこかの設定でその差が生まれていると見て間違いないでしょう。
もうひとつ考えられる原因は、プログラムへ一度に複数のアクセスがあったことによる動作不良。今回のテストでは一度に10回アクセスがあるわけですから、処理し切れなかったのかもしれません。異なるサーバーの画像を呼び出した[7]から[11]の結果が悪かったのは、呼び出しに時間がかかってのタイムアウトが原因と考えるのが妥当でしょうか。プログラムないし画像へのアクセス不良、つまりはサーバーの仕様で表示されなかった、という可能性です。
画像へのアクセス不良が原因という説を裏付けそうな現象があります。はてなブックマークの画像で"1人"と書かれた画像には表示/非表示のばらつきがありましたが、2人、あるいはそれ以上の画像はほぼ毎回表示されていました。他のサイトを見ても"1人"という画像が表示される回数が圧倒的に多いと思われるため、局所的なアクセス集中によるタイムアウト、ということが考えられます。まぁ他の画像も共倒れしそうな気はしますけど。
Opera9.5の不具合を探るつもりが、インターネットの仕組みを調べる長旅に足をつっこんでしまいました。先が見えないうえに、自力ではどう考えても答えまでたどり着きそうにないため、この問題に関してはお蔵入りとさせていただきます。何か原因がつかめそうな方はどうぞ僕の屍を越えていってください。
2008年09月06日 0時更新
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
| « 05月 | - | 07月 » | ||||
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | |||||
