はじめに
* 開発時 や リリース後のアップデート などで、ブラウザに古いJavaScript/CSSなどがキャッシュとして 残っていることがあり、それにより、最新版のモジュールが正しく動作しない事がある。 * キャッシュを抑制するために、Cache-Control : no-cacheなどで対策してもダメな時が多々ある って事で対策を考える
対策案
* 大きく分けて2点[1] ファイル名にバージョンを付加させて管理。(例:<script src="./jquery-1.10.2.js"></script>) => ただし、この方法だと、リリースバージョンを切らない開発時だとキャッシュに残ってしまう => ソース管理している場合、バージョンごとにファイルができるのはイヤ [2] クエリー文字列を付加する(例:<script src="./jquery.js?v=xxxxx"></script>) => こっちがいいかと => クエリー文字列に付加させる情報としては、以下のようなものが考えられる 【クエリー文字列に付加させる情報候補】 2-1) ファイル更新日時 (例:<script src="./jquery.js?date=201602252201413111"></script>) 2-2) 現在日付 2-3) バージョン(例:<script src="./jquery.js?ver=1_10_2"></script>) 2-4) ランダム数・ハッシュ値 などなど => 個人的には、必要時にはファイルを更新し、それ以外はキャッシュを使う方が、 効率がいいわけなので、「2-1) ファイル更新日時」がいいと思う * 何故、クエリー付加させたらキャッシュクリアになるのかは以下のサイトを参照。http://www.koikikukan.com/archives/2011/08/29-015555.php
ASP.NET MVCで実装するには?
[1] クエリー文字列にファイル更新日時を付加させる 1-1) ビュー内で実装する 1-2) ビュー以外(BundleConfigクラスなど)で実装する [2] Bundles.ResolveBundleUrlメソッドを使う # API仕様については、以下のサイトを参照。ハッシュ値を使うらしい。https://msdn.microsoft.com/ja-jp/library/system.web.optimization.bundlecollection.resolvebundleurl.aspx
サンプル
■ 実装1:ビュー内で実装する
@Code ViewData("Title") = "Index" ' ★ここ★ Dim filePath = Server.MapPath(Url.Content("~/Scripts/jquery-1.10.2.js")) Dim fileDate = System.IO.File.GetLastWriteTime(filePath).ToString("yyyyMMddHHmmssfff") End Code <script src="@Url.Content("~/Scripts/HelloWorld.js?date=" & fileDate)" type="text/javascript"></script> ・・・略・・・
出力結果
<script src="/Scripts/HelloWorld.js?date=20160104220752149" type="text/javascript"></script>
■ 実装2:ビュー以外で実装する
Imports System.Web.Optimization Public Module BundleConfig Public Sub RegisterBundles(ByVal bundles As BundleCollection) bundles.Add(New ScriptBundle("~/bundles/jquery").Include( "~/Scripts/jquery-{version}.js")) ' ★ここ★ Dim filePath = Hosting.HostingEnvironment.MapPath("~/Scripts/HelloWorld.js") Dim fileDate = System.IO.File.GetLastWriteTime(filePath).ToString("yyyyMMddHHmmssfff") bundles.Add(New ScriptBundle("~/bundles/jsHello").Include( "~/Scripts/HelloWorld.js?date=" & fileDate)) End Sub End Module
■ 実装3:Bundles.ResolveBundleUrlメソッドを使う
Bundleについては、以下の関連記事を参照のことhttp://blogs.yahoo.co.jp/dk521123/35704775.html
<script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/jsHello")" type="text/javascript"></script>
出力結果
* 軽く実験したが毎回違うハッシュ値ではなく、中身のJSに変更になったら変わるが、変更がなかったら同じハッシュ値だった<script src="/bundles/jsHello?v=BZGaXsRK3rFdbpY0k8ak1Ls0nJDWwbTUS4hURH1dUIo1" type="text/javascript"></script>
参考文献
http://wisdomtrees.net/?p=10PHPだが考え方は非常に参考になった
http://doop-web.com/blog/archives/1182
Bundles.ResolveBundleUrl()について
http://blogs.msdn.com/b/chack/archive/2012/03/27/asp.net-mvc-4-bundling-and-minification-of-css-and-javascript.aspx
ファイル更新日時
http://dobon.net/vb/dotnet/file/filetimestamp.html