如何强制客户端刷新JavaScript文件?

JavaScript

梅小哥

2020-03-12

我们目前正处于非公开Beta测试阶段,因此仍在进行相当快速的更改,尽管显然随着使用量的增加,我们将放慢这个过程。话虽这么说,我们遇到的一个问题是,在我们推出新JavaScript文件的更新后,客户端浏览器仍然使用文件的缓存版本,而他们看不到更新。显然,在技术支持电话上,我们可以简单地通知他们进行ctrlF5刷新以确保他们从服务器获取最新文件,但是最好在此之前进行处理。

我们当前的想法是将版本号简单地附加到JavaScript文件的名称上,然后在进行更改时增加脚本上的版本并更新所有引用。这肯定可以完成工作,但是更新每个发行版上的引用可能会很麻烦。

因为我确定我们不是第一个处理此问题的人,所以我认为我会将它扔给社区。更新代码时,如何确保客户端更新其缓存?如果您使用上述方法,是否正在使用简化更改的过程?

第934篇《如何强制客户端刷新JavaScript文件?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

21个回答
GO村村 2020.03.12

下面为我​​工作:

<head>
<meta charset="UTF-8">
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0" />
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
</head>
飞云小卤蛋 2020.03.12

一种简单的方法。编辑htaccess

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.(jpe?g|bmp|png|gif|css|js|mp3|ogg)$ [NC]
RewriteCond %{QUERY_STRING} !^(.+?&v33|)v=33[^&]*(?:&(.*)|)$ [NC]
RewriteRule ^ %{REQUEST_URI}?v=33 [R=301,L]
Monkey洋 2020.03.12

通过标记帮助器在ASP.NET Core中进行缓存清除将为您解决此问题,并允许浏览器保留缓存的脚本/ css,直到文件更改为止。只需将标签助手asp-append-version =“ true”添加到脚本(js)或链接(css)标签中:

<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true"/>

Dave Paquette在此处提供了一个很好的示例以及缓存清除的说明(页面底部)缓存清除

逆天神奇 2020.03.12

最简单的解决方案?不要让浏览器完全缓存。附加当前时间(以毫秒为单位)作为查询。

(您仍处于测试阶段,因此您可以为不针对性能进行优化提供合理的理由。这里是YMMV。)

Green前端 2020.03.12

尽管它是特定于框架的,但Django 1.4具有此功能,其工作方式与上述答案中指向“ greenfelt”站点的链接类似

Eva阿飞 2020.03.12

使用版本GET变量来防止浏览器缓存。

附加?v=AUTO_INCREMENT_VERSION到网址末尾可防止浏览器缓存-避免任何和所有缓存的脚本。

null 2020.03.12

我在http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack/上发布(参考CSS)后,我的同事刚刚找到了对该方法的引用很高兴看到其他人正在使用它,并且似乎可以正常工作。在这一点上,我认为在所有脚本标签中没有比找到替换增加这些“版本号”更好的方法了吗?

理查德小胖Harry 2020.03.12

一种解决方案是在获取资源时将带有时间戳的查询字符串附加到URL。这利用了以下事实:浏览器将不会缓存从URL中带有查询字符串的资源。

您可能根本不希望浏览器完全不缓存这些资源。您更可能希望将其缓存,但希望浏览器在文件可用时获取新版本。

最常见的解决方案似乎是在文件名本身中嵌入时间戳或修订号。这需要做更多的工作,因为需要修改您的代码以请求正确的文件,但这意味着,例如,您的版本7 snazzy_javascript_file.js(即snazzy_javascript_file_7.js)会在浏览器中缓存,直到您发布版本8,然后您的代码更改为取snazzy_javascript_file_8.js来代替。

小胖Gil 2020.03.12

使用a而file.js?V=1不是a 的优点fileV1.js是您不需要在服务器上存储JavaScript文件的多个版本。

我遇到的问题file.js?V=1是,在使用新版本的库实用程序时,您可能在另一个JavaScript文件中有从属代码会中断。

为了向后兼容,我认为最好jQuery.1.3.js在新页面上使用并让现有页面使用jQuery.1.1.js,直到必要时准备升级旧页面为止。

斯丁JinJinHarry 2020.03.12

在asp.net mvc中,可以将@ DateTime.UtcNow.ToString()用于js文件版本号。版本号随日期自动更改,并且您强制客户端浏览器自动刷新js文件。我使用这种方法,并且效果很好。

<script src="~/JsFilePath/JsFile.js?v=@DateTime.UtcNow.ToString()"></script>
蛋蛋斯丁 2020.03.12

jQuery函数getScript也可以用于确保每次加载页面时确实加载了js文件。

这是我的方法:

$(document).ready(function(){
    $.getScript("../data/playlist.js", function(data, textStatus, jqxhr){
         startProgram();
    });
});

http://api.jquery.com/jQuery.getScript/中检查该功能

默认情况下,$。getScript()将缓存设置设置为false。这会将带时间戳的查询参数附加到请求URL,以确保浏览器在每次请求时都下载脚本。

A村村 2020.03.12

location.reload(true);

参见https://www.w3schools.com/jsref/met_loc_reload.asp

我动态调用这一行代码,以确保已从Web服务器而不是从浏览器的缓存中重新检索了javascript,从而避免了此问题。

Jim老丝L 2020.03.12

并非所有浏览器都以“?”缓存文件 在里面。为了确保尽可能多地对其进行缓存,我在文件名中包含了该版本。

所以stuff.js?123代替了stuff_123.js

我曾用过mod_redirect(我认为)have stuff_*.jsstuff.js

猿乐 2020.03.12

对于ASP.NET,我想使用高级选项(调试/发布模式,版本)的下一个解决方案:

通过以下方式包含的Js或Css文件:

<script type="text/javascript" src="Scripts/exampleScript<%=Global.JsPostfix%>" />
<link rel="stylesheet" type="text/css" href="Css/exampleCss<%=Global.CssPostfix%>" />

Global.JsPostfix和Global.CssPostfix是通过Global.asax中的以下方式计算的:

protected void Application_Start(object sender, EventArgs e)
{
    ...
    string jsVersion = ConfigurationManager.AppSettings["JsVersion"];
    bool updateEveryAppStart = Convert.ToBoolean(ConfigurationManager.AppSettings["UpdateJsEveryAppStart"]);
    int buildNumber = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Revision;
    JsPostfix = "";
#if !DEBUG
    JsPostfix += ".min";
#endif      
    JsPostfix += ".js?" + jsVersion + "_" + buildNumber;
    if (updateEveryAppStart)
    {
        Random rand = new Random();
        JsPosfix += "_" + rand.Next();
    }
    ...
}
Eva前端 2020.03.12

如今,常见的做法是生成内容哈希码作为文件名的一部分,以强制浏览器(尤其是IE)重新加载javascript文件或css文件。

例如,

供应商。a7561fb0e9a071baadb9 .js
main。b746e3eb72875af2caa9 .js

通常,这是构建工具(例如webpack)的工作。如果有人想尝试使用webpack,这里有更多详细信息

Green理查德 2020.03.12

对于ASP.NET页面,我正在使用以下内容

之前

<script src="/Scripts/pages/common.js" type="text/javascript"></script>

之后(强制装弹)

<script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>

添加DateTime.Now.Ticks效果很好。

蛋蛋猿 2020.03.12

如果要生成链接到JS文件的页面,则一种简单的解决方案是将文件的最后修改时间戳记附加到生成的链接。

这与Huppie的答案非常相似,但是可以在没有关键字替换的版本控制系统中使用。这也比追加当前时间更好,因为即使文件完全没有更改,这样做也可以防止缓存。

Stafan猴子 2020.03.12

将当前时间附加到URL确实是一种常见的解决方案。但是,如果需要,也可以在Web服务器级别进行管理。可以将服务器配置为发送JavaScript文件的不同HTTP标头。

例如,要强制将文件缓存不超过1天,您可以发送:

Cache-Control: max-age=86400, must-revalidate

对于Beta版,如果要强制用户始终获取最新版本,则可以使用:

Cache-Control: no-cache, must-revalidate
Harry泡芙 2020.03.12

Google Page-Speed:在URL中不要包含用于静态资源的查询字符串。大多数代理(最著名的是通过3.0版的Squid up)不使用“?”缓存资源。即使响应中存在Cache-control:公共标头,也不会在其URL中显示。要为这些资源启用代理缓存,请从对静态资源的引用中删除查询字符串,然后将参数编码为文件名本身。

In this case, you can include the version into URL ex: http://abc.com/v1.2/script.js and use apache mod_rewrite to redirect the link to http://abc.com/script.js. When you change the version, client browser will update the new file.

老丝Eva 2020.03.12

This usage has been deprected: https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache

这个答案仅晚了6年,但是我在很多地方都看不到这个答案。HTML5引入了用于解决此问题的应用程序缓存我发现我正在编写的新服务器代码使存储在人们浏览器中的旧javascript崩溃,因此我想找到一种使它们的javascript过期的方法。使用清单文件,如下所示:

CACHE MANIFEST
# Aug 14, 2014
/mycode.js

NETWORK:
*

并在每次您希望用户更新其缓存时使用新的时间戳生成该文件。附带说明一下,如果添加了此选项,则在清单通知您之前,浏览器将不会重新加载(即使当用户刷新页面时)。

猴子古一蛋蛋 2020.03.12

据我所知,一个常见的解决方案是?<version>在脚本的src链接中添加一个

例如:

<script type="text/javascript" src="myfile.js?1500"></script>

在这一点上,我认为在所有脚本标签中没有比找到替换增加这些“版本号”更好的方法了吗?

You might have a version control system do that for you? Most version control systems have a way to automatically inject the revision number on check-in for instance.

It would look something like this:

<script type="text/javascript" src="myfile.js?$$REVISION$$"></script>

Of course, there are always better solutions like this one.

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android