ブラウザキャッシュコントロール

画像掲示板の泉はSQL化やPHP出力化を未だやってはいないので、昔ながらのdatログ+html書き出し方式で運営してしまっておりましたが、html書き出し型で問題となるのがブラウザのキャッシュコントロールです。

ブラウザのキャッシュとは、Chrome、Firefox、Safariといったブラウザで、一度アクセスしたサイトの画像やHTMLデータをブラウザで一時的にPCに保管しておく仕組みです。再度同じページを訪問した際、手元にあるキャッシュデータを読み込むことで、インターネット上から読み込むよりも速く表示ができるようになります。

今のように10Mbpsが当たり前といった時代には恩恵を感じる機会も減りましたが、14.4Kbpsや33.6Kbpsのモデムで接続していた時代には、これがないとYahooを開くのも一苦労といった感じがしてました。

とはいえ、このブラウザキャッシュがhtmlファイル更新型の掲示板には厄介な問題を発生させます。

更新されない掲示板

画像掲示板の泉では、スレッドで書き込みをした場合には、その書き込みが一番目立つように、書き込みされたスレッドをスレッド一覧の最上位に移動するようPHPでプログラムしてあります。

ログデータをPHPで読み込み、スレッド毎に配列データとして、書き込みされたスレッドデータをarray_unshift()で先頭に移動で実現していますが、最終的にこれをhtmlファイルに上書きして保存をしたとしても、ブラウザ側でキャッシュを吐きだされてしまうと、せっかくのスレッド並び替え機能も意味がなくなってしまいます。

特に、掲示板のデザインをギャラリー風のタイル並びのようなデザインにしていたので、書き込みしたスレッドがすぐに最上位に上がってくれていないと、書き込みした感が全くでないので非常に残念な感じになってしまいます。

書き込みしたら先頭にスレを持ってくるようにしていますが、
キャッシュを読まれると当然移動前のhtmlのままになります

html <head>のキャッシュコントロール

<head>内の<meta>タグにお決まりのキャッシュコントロールはいれてみましたが、Chromeでうまく動くときもあればSafariではNGだったり、その逆だったりもあり、HTMLでのキャッシュコントロールは非常に弱い感じです。

<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">

他にも、<meta http-equiv=”Expires”>でキャッシュ有効期限を入れてみたりはしてみたものの、状況は全く変わらずでした。

.jsでの強制再リロード

さすがに無理かと思った時、それならJavaScriptで強引にブラウザをリロードさせてしまえばいいんじゃないか?といったことを思いついてしまい、.jsで色々と試してみることにしました。

setTimeout()で強制リロード

最初にやった方法は、とりあえずsetTimeout()でリロードをばんばん走らせてしまえばいいのではというかなりバカな方法です。何も考えずにDOM読み込み後の雑多な処理の一つにsetTimeoutのタイマーでリロード処理を放り込んでみました。

$(function() {
 setTimeout(function() {
  location.reload();
 },30000);
});

setTimeout()メソッドで指定する数値はミリ秒 (1/1000 秒) 単位となるので、とりあえず30,000ミリ秒(30秒)で設定をいれて、掲示板スレに書き込みをしてみました。

書き込み後にジャンルトップページに戻ってみたものの、やはり相変わらず最上位には書き込みしていないスレが上がったままの、キャッシュ側データが表示されておりましたが、しばらくすると、タイマーでブラウザがリロード!見事書き込みスレッドが最上位に表示された最新ファイルを読み込ませることができました。safariでやってもいい感じです。

とりあえずこれでOKということで、全ジャンルの掲示板プログラムやテンプレートの更新をかけて無事作業終了となった時、やっと肝心なことに気が付いてしまいました。

普通の人なら見た瞬間に気付くと思いますが、30秒毎にリロードされたら書き込みなんてできるわけないじゃんということです。

はいその通りでした。

新規投稿をしようと書き込みをしていたら、30秒でリロードが走って書き込み中のコメントが真っ白に。

当たり前ですね。

キャッシュコントロールのことばかり考え、そもそも掲示板で書き込みをするってことをすっかり忘れてしまっておりました。

ということで、また1からやり直しです。

一回だけブラウザをリロード

要は、1回だけリロードさせればいいということなので、調べてみたら似たようなことを質問している方がいらっしゃいました。

とあるページにアクセスした際、JavaScript(jQuery)を使って一度だけページをリロードしたいと思っております。

まさに同じ悩みをお持ちだったようです。このベストアンサーを見ると、 window.nameプロパティに名前を適当に付けて、この指定した名前がなければリロードを走らせるというシンプルな方法を紹介していました。

if(window.name != "reloaded") {
 location.reload();
 window.name = "reloaded"; //適当な名前
}else{
 window.name = "";
}

やってみたところ、無事に1回だけリロードを走らせることができるようになりました。とはいえ、サイトを開いた瞬間に謎の再読み込みが一回走るのが気持ち悪い感じがします。

結論:.htaccessのキャッシュコントロール

<Files ~ "\.(html|php|jpe?g|gif|png|pdf)$">
  Header set Pragma no-cache
  Header set Cache-Control no-cache
</Files>

結論からいうと、.htaccessを使うが一番良い方法と思います

上記のサンプル.htaccessでは、html、php、jpeg、gif、png、pdfなどの拡張子ファイルに対して、応答ヘッダを強制的にサーバ側で設定します。

HTML側に入れても無視されていたno-cacheがしっかり反映されていました。

HTMLにno-cacheが無事設定されてました

おわりに

キャッシュコントロールの問題も無事クリアしましたが、肝心の掲示板へのアクセス数や投稿が増えないのが一番の問題です。アップ画像容量も順次増やしているので、画像アップローダー代わりにでもぜひご利用下さい。

画像掲示板の泉