一部のブラウザ(特にFirefoxとオペラ) は、ブラウザ セッション間でも、 .css ファイルと.jsファイルのキャッシュされたコピーを熱心に使用します。そのため、これらのファイルの 1 つを更新しても、ユーザーのブラウザがキャッシュされたコピーを使用し続けると問題が発生します。
ファイルが変更されたときにユーザーのブラウザにファイルを強制的に再読み込みさせる最もエレガントな方法は何ですか?
理想的なソリューションは、ページにアクセスするたびにブラウザにファイルを再読み込みさせる必要がないことです。
見つけたジョン・ミリキンのそしてda5idの提案は役に立つと思います。実は、これには「自動バージョン管理」という用語があります。
私のオリジナルの解決策と John の提案を組み合わせた新しい回答を以下に掲載しました。
SCdFが提案した別のアイデアは、偽のクエリ文字列をファイルに追加するというものでした。(タイムスタンプを偽のクエリ文字列として自動的に使用するPythonコードは、piによって提出されました。。
ただし、ブラウザがクエリ文字列を含むファイルをキャッシュするかどうかについては議論があります。(ブラウザにファイルをキャッシュさせて、今後のアクセス時に使用させることを希望していることを思い出してください。ファイルが変更された場合にのみ、ファイルを再度取得することを希望します。)
ベストアンサー1
このソリューションは PHP で書かれていますが、他の言語にも簡単に適応できるはずです。
元の.htaccess
正規表現は、 のようなファイルで問題を引き起こす可能性がありますjson-1.3.js
。解決策は、末尾がちょうど 10 桁である場合にのみ書き換えることです。(10 桁は 9/9/2001 から 11/20/2286 までのすべてのタイムスタンプをカバーするため)。
まず、.htaccess で次の書き換えルールを使用します。
RewriteEngine on
RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]
ここで、次の PHP 関数を記述します。
/**
* Given a file, i.e. /css/base.css, replaces it with a string containing the
* file's mtime, i.e. /css/base.1221534296.css.
*
* @param $file The file to be loaded. works on all type of paths.
*/
function auto_version($file) {
if($file[0] !== '/') {
$file = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', dirname($_SERVER['PHP_SELF'])), '/') . '/' . $file;
}
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . $file))
return $file;
$mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);
return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file);
}
ここで、CSS を組み込む場所を次のように変更します。
<link rel="stylesheet" href="/css/base.css" type="text/css" />
これに対して:
<link rel="stylesheet" href="<?php echo auto_version('/css/base.css'); ?>" type="text/css" />
こうすることで、リンク タグを再度変更する必要がなくなり、ユーザーには常に最新の CSS が表示されます。ブラウザは CSS ファイルをキャッシュできますが、CSS に変更を加えると、ブラウザはこれを新しい URL として認識するため、キャッシュされたコピーは使用されません。
これは、画像、ファビコン、JavaScript でも機能します。基本的に、動的に生成されないものなら何でも使用できます。