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

IT技术 javascript caching versioning
2021-01-23 17:33:07

我们目前正在进行内部测试,因此仍在进行相当快速的更改,尽管很明显随着使用量开始增加,我们将放慢此过程。话虽如此,我们遇到的一个问题是,在我们使用新的 JavaScript 文件推出更新后,客户端浏览器仍然使用该文件的缓存版本,并且他们看不到更新。显然,在接到支持电话时,我们可以简单地通知他们进行ctrlF5刷新以确保他们从服务器获取最新文件,但最好在此之前处理此问题。

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

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

6个回答

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

例如:

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

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

你可能有一个版本控制系统为你做这件事?例如,大多数版本控制系统都有一种方法可以在签入时自动注入修订号。

它看起来像这样:

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

当然,总会有更好的解决方案,比如这个

有谁知道IE7是否忽略了这一点?当我在 IE8 可比性视图中测试时,它似乎忽略了附加的数据并使用了缓存的文件。
2021-03-10 17:33:07
我一直知道查询字符串是键值对,如 ?ver=123。谢谢!:)
2021-03-11 17:33:07
为了提高认识:这被认为是一种黑客行为。这种方法诱使浏览器认为正在指定一个新文件,因为它只是查看完整的文件名而不进行解释。foo.js?1与 的名称不同foo.js?2,因此浏览器会认为它们是两个不同的文件。一个缺点是这两个文件将同时存在于用户的缓存中,占用了不必要的空间。
2021-03-11 17:33:07
我认为这不是关于更高或更低的版本号,而是关于将附加变量值更改为浏览器无法缓存的内容。
2021-03-29 17:33:07
@LeeWhite 无论您如何解决问题,这两个文件都将缓存在浏览器中。要么是因为它们有不同的请求参数或不同的路径。所以我不认为这是请求参数方法的缺点。
2021-04-09 17:33:07

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

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

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

对于测试版,如果您想强制用户始终获取最新的,您可以使用:

Cache-Control: no-cache, must-revalidate
Chrome 需要这些设置才能正确缓存。没有它们,Chrome 将永远缓存文件。Mozilla 使用了更合理的默认设置。查看更多信息: agiletribe.wordpress.com/2018/01/29/caching-for-chrome
2021-03-10 17:33:07
你在哪里配置这个?
2021-03-16 17:33:07
他正在谈论 Web 服务器为每个文件发送的标头。例如,应该可以在 Apache 中进行配置。我认为这将是最好的方法
2021-03-17 17:33:07
对于开发 webapp,这可能是一个很好的解决方案。对于生产站点,您不想永远使缓存无效,除非您知道每个目标客户端浏览器都已访问该站点,否则这不是一个好的解决方案这让我想到了一个潜在的 Web 服务器功能:根据配置的部署日期调整 max-age 参数。那将是真棒。
2021-03-19 17:33:07
你能更具体一点吗?
2021-03-24 17:33:07

Google Page-Speed:不要在静态资源的 URL 中包含查询字符串。大多数代理,尤其是 Squid 直到 3.0 版,都不使用“?”缓存资源。即使响应中存在 Cache-control: 公共标头,它们的 URL 中也是如此。要为这些资源启用代理缓存,请从对静态资源的引用中删除查询字符串,并将参数编码到文件名本身中。

在这种情况下,您可以将版本包含在 URL 中,例如:http://abc.com/ v1.2 /script.js 并使用 apache mod_rewrite 将链接重定向到http://abc.com/script.js当您更改版本时,客户端浏览器将更新新文件。

@Hắc Huyền Minh:但是当脚本被重新加载时,它不应该从代理缓存中重新加载......
2021-03-18 17:33:07
我试过了?解决方案,在 IE8 中,我收到一个 javascript 错误。Mod 重写是一种选择,但在大多数情况下,我们不会对服务器进行太多控制。我更喜欢在 js 文件本身中附加版本或为每个版本创建一个文件夹
2021-03-26 17:33:07

此用法已弃用:https : //developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache

这个答案只晚了 6 年,但我在很多地方都没有看到这个答案...... HTML5 引入了Application Cache来解决这个问题。我发现我正在编写的新服务器代码正在使人们浏览器中存储的旧 javascript 崩溃,所以我想找到一种方法来使他们的 javascript 过期。使用如下所示的清单文件:

CACHE MANIFEST
# Aug 14, 2014
/mycode.js

NETWORK:
*

并在每次您希望用户更新其缓存时使用新的时间戳生成此文件。附带说明一下,如果您添加它,浏览器将不会重新加载(即使用户刷新页面),直到清单告诉它。

请阅读文档,因为此功能已从 Web 标准developer.mozilla.org/en-US/docs/Web/HTML/...
2021-03-11 17:33:07
这个解决方案真的很好,只要你记得更新清单文件:)
2021-03-17 17:33:07
现在已弃用!
2021-03-17 17:33:07
FWIW,我最终没有使用这个解决方案。使用/维护该?<version> 方法要容易得多
2021-04-08 17:33:07

如何将文件大小添加为加载参数?

<script type='text/javascript' src='path/to/file/mylibrary.js?filever=<?=filesize('path/to/file/mylibrary.js')?>'></script>

因此,每次更新文件时,“filever”参数都会更改。

当您更新文件并且您的更新结果相同的文件大小时如何?几率有多大?

我最初的想法是添加文件的哈希而不是版本。
2021-03-19 17:33:07
我认为添加 changeate 会比文件大小更好:)
2021-03-20 17:33:07
使用 filemtime($file) 它输出文件的时间戳,使用 time() 你不能使用缓存,因为它每秒钟都在变化。
2021-03-29 17:33:07
我认为如果添加时间戳 Unix 也可以,对吗?例如 '...file.js?filever=<?=time()?>
2021-03-31 17:33:07
这使用 PHP 标签,如果使用 PHP,这确实是一个好主意。
2021-04-04 17:33:07