如何强制浏览器使用版本控制重新加载缓存的静态文件



部署新版本的网站后,浏览器会从旧网页加载其缓存中的所有内容,直到完成硬的强制刷新。

ASP.NET MVC如果文件变为捆绑包,则由优化框架处理。 添加到文件链接的版本,如果捆绑包的文件中发生更改,则会生成新的令牌。 遵循以下代码:

例如,js文件名为:datatables

当您将其放入具有相同名称的捆绑包中时,您将看到

datatables?v=anY9_bo7KitrGnXQr8ITP3ylmhQe9NDzSjgLpLQWQFE1

作为文件名。更改datatables并在浏览器中再次观察文件名,它肯定会更改:

datatables?v=r8yhQBxKyDgrOGyqr1ndtdG92Ije09nqTY7yogrOSTk1

但有两个问题:

  • 如果我们的文件不在捆绑包中,我们该怎么办?
  • 是一种强制浏览器刷新缓存的方法吗?

我们有一个解决方案,有一些不同的实现方式。 我们使用上面的解决方案。

datatables?v=1

我们可以处理文件的版本,这意味着每次我们更改文件时,也要更改文件的版本。 但这不是一个合适的方法。

另一种使用指南的方式,它也不适合,因为每次它都获取文件并且不从浏览器缓存中使用。

datatables?v=Guid.NewGuid()

最后一种最好的方法是:

当文件更改发生时,也更改版本。 检查以下代码:

<script src="~/scripts/main.js?v=@File.GetLastWriteTime(Server.MapPath("/scripts/main.js")).ToString("yyyyMMddHHmmss")"></script>

这样,当您更改文件时,LastWriteTime也会更改,因此文件的版本将更改,并且在下一个打开浏览器时,它会检测到一个新文件并获取它。

假设由于某种原因无法使用捆绑,原始海报建议的解决方案已经足够好了,但是最好将逻辑放在帮助程序方法中。

使代码可测试,它有助于在不更改.cshtml的情况下更改逻辑,并且还有助于不重复文件名两次。然后你可以有一个更干净的代码:

<script src="@Url.ContentWithVersion("~/scripts/main.js")"></script>

为此,您可以将ContentWithVersion扩展方法添加到现有UrlHelper

using System;
using System.IO;
using System.Web;
using System.Web.Mvc;
public static class UrlHelperExtensions
{
    public static string ContentWithVersion(this UrlHelper urlHelper, string path)
    {
        if (urlHelper == null)
            throw new ArgumentNullException(nameof(urlHelper));
        var result = urlHelper.Content(path);
        var file = HttpContext.Current.Server.MapPath(path);
        if (File.Exists(file))
            result += $"?v={File.GetLastWriteTime(file).ToString("yyyyMMddHHmmss")}";
        return result;
    }
}

最新更新