为什么获胜't客户端在公用文件夹中接收此脚本的新版本

Why won't the client receive new versions of this script in the public folder?

本文关键字:文件夹 新版本 脚本 获胜 客户端 为什么      更新时间:2024-01-01

在我的项目中,有一个公用文件夹和一个脚本:public/worker.js,其中包含一段代码:

alert('foo');

我使用Worker:调用此脚本

new Worker('worker.js');

我启动Meteor并连接到我的应用程序。CCD_ 2被提醒
如果我将public/worker.js代码更改为其他代码:

alert('bar');

服务器刷新客户端,客户端刷新页面但不会得到新代码,而是使用旧代码(提醒foo而不是新的闪亮的bar)。清除缓存然后刷新可修复此问题。CTRL+F5并没有解决这个缓存问题,它似乎不适用于这种脚本调用(至少在我测试过的Firefox版本上不适用)。

究竟为什么会发生这种情况
我该如何预防?

您应该更改文件的响应标头。也许这会让你开始:Meteor';s公共目录

脚本被缓存,浏览器不会从服务器中提取新版本。

我们需要在服务器端使用以下代码编辑/workers文件夹中文件的请求标头(我用api.use('webapp')将其封装在一个包中):

WebApp.rawConnectHandlers.use('/workers', function(req, res, next) {
  res.setHeader('cache-control', 'must-revalidate');
  next();
});

使用WebApp.connectHandlers不起作用,回调从未被调用,所以我使用了rawConnectHandlers

我不能百分之百肯定这是最好的方式,但它是有效的。

我还没有找到确切的原因,但浏览器(至少是Chrome)似乎在页面刷新时缓存工作脚本与其他Javascript文件不同,即使从服务器发送的头是相同的。刷新页面会使浏览器检查脚本标记中引用的新脚本,但不会检查用作辅助程序的脚本。

我解决这个问题的方法是,在构建时,我在文件名中包含文件内容的版本号/build-time/md5,所以它最终会变成worker.12333.js。这样做的好处是,如果每个文件名都引用了一个基本上不可变的文件,则可以设置远期过期的头。。。因此,与其告诉浏览器永远不要缓存工作脚本,它可以永远缓存它。https://github.com/felthy/grunt-cachebuster是一个这样的工具,它通过脚本标签为Javascript提供了这一功能,但可能还有其他工具。

这样做的问题是,必须有某种机制来告诉Javascript更新的文件名,这样它就知道调用new Worker('worker.12333.js');。我不确定现有的可用工具是否能处理这一问题,但我这样做的方式是只使用以秒为单位的项目构建时间作为所有文件的唯一密钥

<html build-time="12333">
  ...

然后通过Javascript访问它,这样它就可以计算出最新的工作脚本文件名。它并不完美,但相当简单。根据您的需求,您可能会想出其他机制。