更新時にキャッシュを無効にしたい

見出し右端の記号は?

Web Page
Booskanium's Tips.
忘れっぽい落書き人のメモ

無駄な読み込みをさせないためにブラウザは訪問したウェブページをキャッシュします。しかしコンテンツを更新したときや、ウェブアプリの場合には困ります。HTML&CSS&JavaScriptの連携バージョンが合わないと動作不定になります。
ユーザー側で出来ることは、ウェブページのリロードです。ブラウザによっても操作方法が異なるのでややこしい。

Chrome

Chromeのキャッシュは強力です。そのキャッシュを確実に消す方法は「F12 → 更新マークをマウスで長押し → キャッシュと消去とハード再読み込み」です。
リロードで無効になるキャッシュ削除もあります。操作方法は「Shift + 更新マーククリック」「Ctrl + 更新マーククリック」「Shift + F5」「Ctrl + F5」「Ctrl + Shift + R」などがあります。この方法では必ずしも新しいページが読み込まれるとは限りません。
Androidでは面倒な設定から削除するしかないので少々面倒です。

Firefox

Firedoxでキャッシュを確実に消す方法は「オプション → プライバシーとセキュリティ → Cookie とサイトデータ → データ消去」です。なを全ウェブページのキャッシュが消えます。
リロードで無効になるキャッシュ削除もあります。操作方法は「Ctrl + Shift + R」「Ctrl + F5」です。この方法では必ずしも新しいページが読み込まれるとは限りません。
Androidでは面倒な設定から削除するしかないので少々面倒です。

コンテンツ側でキャッシュを回避する考慮

キャッシュさせないメタタグはHTML5ではNG

メタタグで
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
と言いたいところですが、残念ながらHTML5では無効な指定です。それでもブラウザは解釈してくれるかもしれません。
仕様では“<!DOCTYPE ~”でHTML4.x以前であることをブラウザに知らせた時のみです。
HTML4.x以前でもブラウザによってキャッシュの考え方が違っていました。

HTML5はService Workers

当初はCache Menifestを使うという話でしたが、これはHTML5.1で廃止、HTML5.2で衰退させてゆく技術として復活(iOS対応)をなった様です。
代わりにService WorkersのCache storageとか言うのを使うらしい。しかしiOSの古いSafariが未対応なので、iOSのライフサイクル切れを待つのかな?
iOS+Safariは第二のIE化してきていますね。
HTML5でキャッシュをねじ伏せる方法はまだ調査中です。

HTTPヘッダでブラウザキャッシュを阻止

PHPなら

PHPなどのサーバーアプリなら、HTTP HeaderでExpires(有効期限)が簡単に吐き出せるので、キャッシュを無効化するのは容易です。

静的はHTMLページ

静的なホームページなら、.htaccessに以下を記述して、HTTP Headerを追加する方法もあります。
<Files ~ "\.(html|php|jpe?g|gif|png|css|js|pdf)$">
Header add Pragma "no-cache"
Header set Cache-Control no-cache
</Files>
残念ながら落書き人が利用しているレンタルサーバーでこれを設定すると、インターナルエラーになってしまいます。
これ以外にも利用中のレンタルサーバーは、応答が遅いなどの不満がありますので引っ越そうと強く思っています。

CSSやJavaScriptファイルの読み込み

cssやjsファイルを変更した時には「~.css?202008130921」の様に日時分の値を引数として付与してリロードさせる。
cssやJavaScriptを更新したので反映されないというミスを回避できます。
ウェブアプリの場合は、URL引数に乱数のダミー引数をセットして、常にリロードされる様にします。

が、しかしChromeではこのURL引数を変化させても、無視してキャッシュから読み込むようです。

XHRでデータ読み込みのキャッシュ回避

「'~URL文字列~?' + String((new Date()).getTime())」という具合にUNIX時間を付加してキャッシュから読み込まれるのを回避しています。