🐷

ブラウザのキャッシュを無効化する方法

2021/06/15に公開

ブラウザのキャッシュについてググると、情報が新旧織り交ざってヒットするので、ちょっと整理しておきます。

従前のMETAタグによる方法

HTML5(本記事ではHTML Living standardと区別しない)では、http-equiv属性に対してキャッシュに関するキーワード(PragmaCache-ControlExpires)を指定できなくなりました。

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

新規案件で、HTML4.01やXHTML1.0でコーディングすることは無くなったので、上記指定方法は綺麗さっぱり忘れましょう。
また、代替手段として Application Cache API(AppCache) がありましたが、現在では非推奨になっているので、これも忘れましょう。

Cache Busting

CSSやJavaScriptなどの静的ファイルでは、Cache Bustingとかキャッシュバスターと呼ばれる方法で、キャッシュを一時無効にしているコードを良く見かけます。
GETパラメータのクエリストリングを変えるとブラウザは異なるURLと認識するため、キャッシュを読まずに最新ファイルを再取得してくれます。

<link href="https://example.com/css/style.css?ver=210615" rel="stylesheet">

style.css?ver=210615ver はダミーなので style.css?210615 と短くしても問題ありません。筆者は大概リリース日付にしてます。

HTTPレスポンスヘッダで制御

ブラウザのキャッシュだけでなく、プロキシやCDNにも使える方法で、より細かく制御できます。
例えばApacheなら、htaccessを次のように指定すると画像コンテンツのみキャッシュを無効にできます。(AllowOverride Allでhtaccessが有効、かつ、mod_headersが有効であること)

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

PHPなら、

<?php
header('Cache-Control: no-cache');

と書けますね。

定義が本当に反映されているかを確認するならChromeデベロッパーツールが便利です。

ちなみに大手CDNベンダ各社(Akamai、Fastly、Cloudflare)は、CDNキャッシュに特化した新ヘッダ仕様CDN-Cache-Controlを共同提案していて、Cloudflareは既に実装されています。

JavaScriptでキャッシュを無視

JavaScriptからlocation.reload(true)でスーパーリロードするのは現在は非推奨になっています。
画像を再読み込みしたいとき、筆者は次のようにしています。(要jQuery)

$('.container img').each(function(index, element) {
  const src = $(element).attr('src');
  $(element).attr('src', src + '?' + new Date().getTime());
});

container配下すべてのimgタグのsrc属性を書き替えることでCache Bustingで再読み込みするコードです。1日に1回だけ更新される画像ならgetTime()toDateString()に変えた方が効率的です。

Discussion