CSSファイルやJavaScriptファイルを読み込むときの末尾にあるクエリー文字列は何のためにあるか
あちこちのウェブサイトのHTMLソースを見ると、CSSファイルやJSファイルを読み込むlink要素やscript要素のファイル名の末尾に「?xxx=123」のような、いわゆるクエリーがついているのを頻繁にみかけます。
例えばWordPressでjqueryを読み込んだときなど、
<script src="http://user-domian/wp-includes/js/jquery/jquery.js?ver=1.6.1"></script>
と、jQueryのバージョン番号を示すクエリー文字列がついています。CSSファイルやJavaScriptファイルはCGIではないので、このクエリーを解釈して使っている訳ではありません。
知っている人は「な~んだ」って感じだと思いますが、この「?ver=1.6.1」の役割について紹介します。
1.キャッシュを制御する
ページ読み込みと同時に読み込まれるCSSやJavaScriptの内容はブラウザキャッシュに読み込まれ、ページを強制リロードしない限りブラウザキャッシュの内容が適用されるようです(詳細は4項参照)。
ですが、CSSファイルやJavaScriptファイルを更新してもキャッシュの内容が適用され続けるのは困るので、クエリー文字列を使って制御します。
具体的には、クエリーのバージョン番号やタイムスタンプを更新すると、ブラウザはそのクエリーつきのURLを「まだ取得していないファイルだ」と認識して、キャッシュから読み込まずに、サーバのファイルを取得します。
この手法はCSSファイルやJavaScriptファイル以外でも使えます。
2.クエリーが変更されないとキャッシュを使う理由
そういうものかと思ってこの技をなんとなく使っている訳ですが、ふと、HTTPの仕様として「クエリーが変更されないとキャッシュを利用する」ということがどこかに規定されているのではないかと思いました。
調べてみたところ、RFC2616の「13 Caching in HTTP」の「13.9 Side Effects of GET and HEAD」にそれらしき記述があるなので日本語訳から引用し、該当すると思われる箇所を赤字で示します。
ハイパーテキスト転送プロトコル -- HTTP/1.1 - 13.9 GET や HEAD の副作用
オリジンサーバがそれらのレスポンスのキャッシングを明示的に禁止していない場合に、あらゆるリソースへ GET や HEAD メソッドを適用する事によってそれらのレスポンスがキャッシュから取り出されたならば、誤った動作を導くような副作用を抱えるべきではない。それらは副作用を抱えるかもしれないが、キャッシュはそのキャッシング決定においてそのような副作用を考慮必要は無い。キャッシュは常にキャッシングにおいてオリジンサーバの明示的な制限を観察する事が期待される。
この規則の一つの例外について記す。アプリケーションの中には伝統的に重要な副作用を抱えた操作を実行するためにクエリ URL (それらは rel_path 部分に "?" を含んでいる) を伴う GET や HEAD を使用しているものがあるので、キャッシュはサーバが明示的有効期限を与えていなければそのようなURI へのレスポンスを新鮮であるように扱ってはならない。これは、そのような URI に対する HTTP/1.0 サーバからのレスポンスはキャッシュから取り出されるべきではない という事を特に意味している。関連する情報については section 9.1.1 参照。
「この部分ではない」ということであれば記事を修正しますので、ご指摘ください。
3.jQueryでキャッシュをクリアする
話がまったく横道にそれますが、キャッシュつながりということで、jQueryのAjaxで読み込むファイルのキャッシュをクリアする方法も掲載しておきます。
キャッシュをクリアするには、cacheプロパティを利用します。
$.ajax({
url: 'http://user-domain/',
type: 'GET',
cache: false,
success: function (data) {
//
}
});
ajaxSetupでも設定可能です。
$.ajaxSetup({
cache: false
});
$('#foo').load('http://user-domain/');
4.実験結果
本当にブラウザキャッシュが使われているのかどうか、FirefoxのLive HTTP Headersを使って、当ブログのトップページのHTTPヘッダを確認してみました。
初回に読み込まれるCSSやJavaScriptは「200 OK」で返却されます。
2回目以降のアクセス(ロケーションバーにカーソルをあててリターン)ではリクエスト自体が送信されておらず、ブラウザキャッシュが利用されているものと考えます。
リロードボタンを押すとサーバにリクエストが送信されますが、サーバは「304 Not Modified」を返却(=ブラウザキャッシュを利用)します。
強制リロード(Shift+リロードボタンまたはCtrl+F5)では、サーバから「200 OK」が返却されます。
また、本題であるクエリーを変更した直後も「200 OK」が返却されました。
- YouTube動画にキャプションをつけてテキストを回り込ませる方法
- 画像を下揃えにしてテキストを回り込ませる方法
- style要素にCSSの擬似要素は記述可能か?
- position:relativeを設定すると他の要素がずれる場合の対処
- CSSでタブ切り替えする方法
- :target擬似クラスのまとめ
- CSSでヘッダを固定したスクロールテーブルを作る方法
- レスポンシブウェブデザインで画像を縮小する方法
- disabledなボタンのhoverのスタイルを無効にする方法
- HTML要素を別の要素を基点にしてCSSで絶対配置する方法
- :not擬似クラスでCSS3のサポートをチェックする方法
- :checked擬似クラスでチェックボックスに連動して要素を表示させる方法
- ol要素の入れ子で親の番号を子に割り当てる方法
- チェックボックスやラジオボタンを大きくする方法
- CSSで中央に配置する方法