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

kie*_*iev 96 .net javascript c# asp.net asp.net-mvc

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

我刚刚实现了这个似乎有用的解决方案.

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

  public string version { get; set; }
Run Code Online (Sandbox Code Playgroud)

从web.config键获取版本号

 version = ConfigurationManager.AppSettings["versionNumber"];
Run Code Online (Sandbox Code Playgroud)

在您的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" />
Run Code Online (Sandbox Code Playgroud)

因此,如果您在web.config中将1.0设置为版本= 1.1,您的浏览器将下载最新文件,这有望为您和您的用户带来一些挫败感.

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

Ada*_*gen 70

我通过将最后修改的时间戳作为脚本的查询参数来解决这个问题.

我用扩展方法做了这个,并在我的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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在CSHTML页面中:

 @Html.IncludeVersionedJs("/MyJavascriptFile.js")
Run Code Online (Sandbox Code Playgroud)

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

 <script type='text/javascript' src='/MyJavascriptFile.js?20111129120000'></script>
Run Code Online (Sandbox Code Playgroud)

  • 对页面性能有什么影响?加载页面会导致多少延迟? (2认同)

Dan*_*llo 26

你的解决方案有效 事实上这很受欢迎.

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

<link rel="stylesheet" href="http://sstatic.net/so/all.css?v=6184"> 
Run Code Online (Sandbox Code Playgroud)

v=6184SVN版本号可能在哪里.

  • 您可以在构建期间获取修订版号,将其写入文件(例如部分.cs文件),在项目中包含该文件,因此您无需在运行时从svn读取它.我已经在msbuild中使用这种方法将修订号放在svn的AssemblyInfo.cs文件中. (2认同)
  • 使用全局版本/修订版号至少有一个缺点:发布网站更新会使所有.js和.css文件的浏览器缓存无效,而不仅仅是更改的文件.这在大多数应用程序中可能无关紧要,但我提到它的完整性. (2认同)

met*_*art 23

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" />
Run Code Online (Sandbox Code Playgroud)


jon*_*827 18

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

如果你有大量的JS/CSS文件,这也会有所帮助,因为它可以大大改善内容加载时间!

看这里


小智 12

asp.net中有一个内置的方法:捆绑.只是使用它.每个新版本都有唯一的后缀"?v = XXXXXXX".在调试模式下,捆绑已关闭,用于在web.config中启用make设置:

<system.web>
    <compilation debug="false" />
</system.web>
Run Code Online (Sandbox Code Playgroud)

或者添加方法RegisterBundles(BundleCollection包):

BundleTable.EnableOptimizations = true;
Run Code Online (Sandbox Code Playgroud)

例如:

BundleConfig.cs:

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

bundles.Add(new StyleBundle("~/Content/mystyle.css")
                .Include("~/Content/mystyle.css"));
Run Code Online (Sandbox Code Playgroud)

_Layout.cshtml:

@Scripts.Render("~/Scripts/myjavascript.js")
@Styles.Render("~/Content/mystyle.css")
Run Code Online (Sandbox Code Playgroud)

  • 这应该是标记为正确的答案. (2认同)

sni*_*erd 6

我想要一个简单的单线来使路径独特以破坏缓存。这对我有用:

<script src="scripts/main.js?bust_js_cache=<%=System.IO.File.GetLastWriteTime(Server.MapPath("scripts/main.js")).ToString("HH:mm:ss")%>" type="text/javascript"></script>
Run Code Online (Sandbox Code Playgroud)

如果文件自上次加载到页面后被修改,浏览器将拉取更新后的文件。

last modified.js文件生成图章并将其放入其中,而不是可能不容易访问的版本。

<script src="scripts/main.js?bust_js_cache=10:18:38" type="text/javascript"></script>
Run Code Online (Sandbox Code Playgroud)

另一种选择是获取文件的校验和。


Jac*_*ter 5

这个问题的答案比操作中操作员给出的答案更简单(方法相同):

在web.config中定义密钥:

<add key="VersionNumber" value="06032014"/>
Run Code Online (Sandbox Code Playgroud)

直接从aspx页面调用appsettings:

<link href="styles/navigation.css?v=<%=ConfigurationManager.AppSettings("VersionNumber")%>" rel="stylesheet" type="text/css" />
Run Code Online (Sandbox Code Playgroud)


Bry*_*yan 5

基于Adam Tegan 的答案,经过修改以用于网络表单应用程序。

在.cs类代码中:

public static class FileUtility
{
    public static string SetJsVersion(HttpContext context, string filename) {
        string version = GetJsFileVersion(context, filename);
        return filename + version;
    }

    private static string GetJsFileVersion(HttpContext context, string filename)
    {
        if (context.Cache[filename] == null)
        {
            string filePhysicalPath = context.Server.MapPath(filename);

            string version = "?v=" + GetFileLastModifiedDateTime(context, filePhysicalPath, "yyyyMMddhhmmss");

            return version;
        }
        else
        {
            return string.Empty;
        }
    }

    public static string GetFileLastModifiedDateTime(HttpContext context, string filePath, string dateFormat)
    {
        return new System.IO.FileInfo(filePath).LastWriteTime.ToString(dateFormat);
    }
}
Run Code Online (Sandbox Code Playgroud)

在 aspx 标记中:

<script type="text/javascript" src='<%= FileUtility.SetJsVersion(Context,"/js/exampleJavaScriptFile.js") %>'></script>
Run Code Online (Sandbox Code Playgroud)

在渲染的 HTML 中,它显示为

<script type="text/javascript" src='/js/exampleJavaScriptFile.js?v=20150402021544'></script>
Run Code Online (Sandbox Code Playgroud)

  • 嘿!您的示例正在运行,但您应该删除缓存引用或修复代码以使用缓存,因为它可能会令人困惑您使用它的原因。要使用缓存,您应该在 context.Cache[filename] == null 的情况下使用 context.Cache.Add 方法将文件的版本添加到缓存中。如果 context.Cache[filename] != null 那么你应该返回缓存的值 (context.Cache[filename]) (2认同)