大部分的浏览器都支持缓存功能,但这也是柄双刃剑,好的一面是它可以有效地缓解服务器的压力,不好的一面是当服务器上某个文件(比如js,css)发生变更时,由于浏览器的缓存导致文件没有更新成功。
用户是不会知道变更的,也不会去清理缓存。因此会有一系列的麻烦出现,如何才能有效地解决这个问题呢?
很简单,浏览器支持在文件后面加上?version=xxx
,就可以知道当前的文件是从本地获取还是从服务器获取。只要访问的版本号发生了变化,那么就会从服务器上获取更新。
每次从配置文件去读取版本号,有点劳民伤财的意思,除非你有特殊需求,最好可以支持部署时自动生成版本号。以下代码可以实现,根据当前程序集的发布时间作为版本号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public static class VersionUtils { public readonly static DateTime VersionDate;
public readonly static Int32 VersionNumber;
static VersionUtils() { VersionDate = System.IO.File.GetLastWriteTime(typeof(VersionUtils).Assembly.Location); VersionNumber = Int32.Parse(VersionDate.ToString("yyyyMMddHHmm")); } }
public static class HtmlHelperExtension { public static MvcHtmlString Script(this HtmlHelper html, string contentPath) { return VersionedContent(html, "<script src=\"{0}\" type=\"text/javascript\"></script>", contentPath); }
public static MvcHtmlString Style(this HtmlHelper html, string contentPath) { return VersionedContent(html, "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\">", contentPath); }
private static MvcHtmlString VersionedContent(this HtmlHelper html, string template, string contentPath) { contentPath = UrlHelper.GenerateContentUrl(contentPath, html.ViewContext.HttpContext) + "?v=" + VersionUtils.VersionNumber; return MvcHtmlString.Create(string.Format(template, contentPath)); } }
public static class UrlHelperExtension { public static string ContentVersioned(this UrlHelper urlHelper, string contentPath) { return String.Format("{0}?v={1}", urlHelper.Content(contentPath), VersionUtils.VersionNumber); }
}
|
使用方法
1 2 3
| <link href="@Url.ContentVersioned("~/Content/Site.css")" rel="stylesheet" type="text/css" /> @Html.Style("~/Content/bootstrap.css"); @Html.Script("~/Scripts/angular.js");
|
参考文章
https://github.com/yuanrui/blog/issues/1