画像掲示板の泉」に投稿した後にサイトをみても、ブラウザのキャッシュコントロールが原因で更新されない状態となってしまうといった問題が発生していたため、キャッシュコントロールについて色々と調査をして、最終的には.htaccessによるキャッシュコントロールで解決を図ることができておりました。

結局のところ、HTMLのタグレベルでキャッシュコントロールを解決するなんてことは全く無理で、jsでブラウザをリロードさせるという方法から、掲示板にアクセスしたタイミングで1度だけリロードさせるという策に一旦落ち着いておりましたが、サイト訪問時にリロードが走るという気持ち悪い動きをすることになっていましたので、何か良い方法がないかと探し続けていたところ、.htaccessでno-cacheを設定する方法に辿り着くことができました。

この記事では、そんなブラウザのキャッシュコントロールを解決するまでに試した、様々な対策についてご紹介したいと思います。

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

画像掲示板の泉」は、プログラム出力化といったことを未だできておりませんので、昔ながらのファイルログ+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回だけリロードを走らせることができるようになりました。サイトを開いた瞬間に謎の再読み込みが一回走るのが気持ち悪い感じがしますが、やりたいことはできておりますので、しばらくはこれで走ってしまっておりました。

が、この気持ち悪い動きが何らかのスパムや不正とGoogleに思われるのも嫌だったので、キャッシュコントロールについては継続して調べ続けておりました。そんな時に思いついたものが、.htaccessを使った方法です。

結論:.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をしっかり反映させることができました。

ブラウザで制御されていたCache-Controlがno-cacheとなった
HTMLにno-cacheが無事設定されてました

おわりに

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