强制浏览器在 asp.net 应用程序中获取最新的 js 和 css 文件

IT技术 javascript c# asp.net .net asp.net-mvc
2021-02-11 14:18:24

一些浏览器会缓存 js 和 css 文件,除非您强制刷新它们,否则无法刷新它们。最简单的方法是什么。

我刚刚实施了这个似乎有效的解决方案。

在页面上声明一个版本变量

  public string version { get; set; }

从 web.config 键中获取版本号

 version = ConfigurationManager.AppSettings["versionNumber"];

在您的 aspx 页面中,像这样调用 javascript 和样式表

<script src="scripts/myjavascript.js?v=<%=version %>" type="text/javascript"></script>
<link href="styles/mystyle.css?v=<%=version %>" rel="stylesheet" type="text/css" />

因此,如果您在 web.config 中从 1.0 设置 version = 1.1,您的浏览器将下载最新的文件,这有望为您和您的用户节省一些麻烦。

是否有其他更好的解决方案,或者这是否会导致网站出现任何不可预见的问题?

6个回答

我通过将最后修改的时间戳作为查询参数添加到脚本中解决了这个问题。

我使用扩展方法做到了这一点,并在我的 CSHTML 文件中使用它。 注意:此实现将时间戳缓存 1 分钟,因此我们不会对磁盘​​进行过多的抖动。

下面是扩展方法:

public static class JavascriptExtension {
    public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename) {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
    }

    private static string GetVersion(this HtmlHelper helper, string filename)
    {
        var context = helper.ViewContext.RequestContext.HttpContext;

        if (context.Cache[filename] == null)
        {
            var physicalPath = context.Server.MapPath(filename);
            var version = $"?v={new System.IO.FileInfo(physicalPath).LastWriteTime.ToString("MMddHHmmss")}";
            context.Cache.Add(filename, version, null,
              DateTime.Now.AddMinutes(5), TimeSpan.Zero,
              CacheItemPriority.Normal, null);
            return version;
        }
        else
        {
            return context.Cache[filename] as string;
        }
    }
}

然后在 CSHTML 页面中:

 @Html.IncludeVersionedJs("/MyJavascriptFile.js")

在呈现的 HTML 中,这显示为:

 <script type='text/javascript' src='/MyJavascriptFile.js?20111129120000'></script>
这是标准方式,大多数应用程序遵循。但是,只有在部署或构建应用程序时,该时间戳才会更改。否则每次用户刷新页面或切换到应用程序中的其他页面时。浏览器会再次下载你所有的样式表和 javascript,这不好
2021-03-26 14:18:24
这对 mvc 非常有用,我想知道最新的 mvc 5 框架是否处理了这个问题?捆绑使用 -{version} 通配符的方法也是解决此问题的一种方法,但是它需要在每次新构建后重命名文件...
2021-04-01 14:18:24
对页面性能有什么影响?加载页面会导致多少延迟?
2021-04-04 14:18:24
是否有任何理由担心显示资源文件的最后修改日期/时间戳?如果正在使用的文件具有几年前的日期/时间戳,那么公司可能不希望向其用户公开这些信息吗?
2021-04-09 14:18:24
我在 webforms 网站中使用了您的 MVC 示例的基础知识,它运行良好,所以感谢您的分享!
2021-04-12 14:18:24

ASP.NET Core (MVC 6) 中,这是通过asp-append-version标签助手开箱即用的

<script src="scripts/myjavascript.js" asp-append-version="true"></script>
<link href="styles/mystyle.css rel="stylesheet" asp-append-version="true" />
感谢您让我们知道!我以前不知道!
2021-03-19 14:18:24

您的解决方案有效。事实上,它很受欢迎。

甚至 Stack Overflow 也使用类似的方法:

<link rel="stylesheet" href="http://sstatic.net/so/all.css?v=6184"> 

v=6184SVN 修订号可能在哪里

使用全球版本/修订号至少有一个缺点:发布网站更新会使所有 .js 和 .css 文件的浏览器缓存失效,而不仅仅是更改的文件。这在大多数应用程序中可能无关紧要,但我提到它是为了完整性。
2021-03-16 14:18:24
如果在部署或构建期间自动更新 assemblyinfo.cs 文件的版本,则次要版本可用于该编号。
2021-04-01 14:18:24
您可以在构建期间获取修订号,将其写入文件(例如部分 .cs 文件),将该文件包含在您的项目中,因此您无需在运行时从 svn 读取它。我已经将这种方法与 msbuild 一起使用,将修订号放入我的 svn 的 AssemblyInfo.cs 文件中。
2021-04-03 14:18:24
这将是一种比接受的答案中描述的方法更费力的方法。每次提供页面时检查文件的 SVN 版本是一种性能开销,特别是随着用户数量随着时间的推移而增加。
2021-04-06 14:18:24

如果您为 JS/CSS 使用包,ASP.NET MVC 将为您处理这个问题。它会自动以 GUID 的形式将版本号附加到您的包中,并且仅在包更新时更新此 GUID(也就是任何源文件有更改)。

如果您有大量 JS/CSS 文件,这也很有帮助,因为它可以大大缩短内容加载时间!

看这里

并且不要忘记,作为开发人员,您仍然头疼。ASP.NET 捆绑在调试和开发过程中毫无帮助。
2021-03-17 14:18:24
对,就是这样。只要您的脚本包含在包中,当在任何包的源文件中检测到更改时,它就会自动为每个包生成一个版本号。
2021-03-29 14:18:24
您的意思是如果我们在 MVC 应用程序中使用捆绑包,则不需要此处发布的答案中的任何方法?如果是这样,捆绑真的比我想象的要重要得多。您能否就这些问题向我们澄清一下?谢谢。
2021-04-14 14:18:24

asp.net 中有一个内置的方法:捆绑就用它。每个新版本都有唯一的后缀“?v=XXXXXXX”。在调试模式下,捆绑关闭,用于打开 web.config 中的 make 设置:

<system.web>
    <compilation debug="false" />
</system.web>

或者添加到方法 RegisterBundles(BundleCollection bundles) :

BundleTable.EnableOptimizations = true;

例如:

BundleConfig.cs :

bundles.Add(new ScriptBundle("~/Scripts/myjavascript.js")
                .Include("~/Scripts/myjavascript.js"));

bundles.Add(new StyleBundle("~/Content/mystyle.css")
                .Include("~/Content/mystyle.css"));

_Layout.cshtml :

@Scripts.Render("~/Scripts/myjavascript.js")
@Styles.Render("~/Content/mystyle.css")
是的,bundlind 并没有让开发人员的生活更轻松。每次脚本更改后,您都必须按 Ctrl-F5。如果你有框架,它会更有趣。
2021-03-24 14:18:24
但这仅适用于发布或生产环境。调试模式打开时的开发怎么样?捆绑是否仍然解决此问题?
2021-04-10 14:18:24