我正在使用webpack捆绑我的所有文件。在webpack中,我使用chunkhash,Md5Hash和manifest为我的每个文件生成独特的chunkhash,这些文件可以通过浏览器下载。它看起来像这样。
styles.3840duiel348fdjh385idfki.css
bundle.488503289dfksdlkor93lfui.js
vendor.sdkkfuuewkf892377rfkjdle.js
image.dkkdiiue9984ujjkfld003kfpp.png
这意味着浏览器可以缓存它们,如果没有更改哈希,它将使用缓存版本。同时我可以只更改样式,只有那个哈希值会被更改,所以当我部署应用程序浏览器时仅下载新样式。
问题是我的服务器上使用了这个:
Cache-Control: public max-age=31536000
这表示积极的缓存,浏览器将使用缓存版本一年,除非更改URL,文件名。例如,当我更改样式时,我的哈希值会发生变化,浏览器应该从服务器请求新样式。这是根据这篇文章(模式1)和我发现的更多 https://jakearchibald.com/2016/caching-best-practices/
我的问题是,当我更新某些内容时,示例样式,样式的哈希值会更改,我会部署它。浏览器不会在我的页面上请求重新加载的新样式。它将服务于缓存的文件。我该如何解决这个问题?
我可以使用Cache-Control: no-cache
但这不是解决方案,因为浏览器每次都必须检查服务器是否可以使用缓存版本。这是每次有人访问该页面时不需要的4个http请求。
答案 0 :(得分:1)
我解决这个问题的方法是在我的文件名中添加一个数字(即Date.now()),如下所示。
文件名:[name].${Date.now().valueOf()}.[chunkhash].js
这在可预见的时间内非常可靠地工作。我用这种方法看到的唯一缺点是:每次发布时,都会强制刷新所有包。
但是,有些情况下,当模块不更改但其顺序发生变化(因此模块ID)时,渲染chunkhash会产生问题。模块ID和顺序不是chunkhash的一部分!请参阅:https://github.com/webpack/webpack/issues/1856
其他替代方法是使用命名模块(我相信会产生一些性能影响),除此之外可能涉及命名我不确定的模块。
答案 1 :(得分:0)
Cache-Control: public max-age=31536000
,如我的问题所述。对于服务于html(ejs)的服务器包,我使用Cache-Control: no-cache
。这很好用,因为浏览器会在每次重新加载时联系服务器,但这只是一个http请求。如果没有更改,浏览器将使用所有资产的缓存版本,因为html中的chunkhash没有更改。
例如,如果我更新了样式并且chunkhash被更改,浏览器将会看到在重新加载时联系服务器时只会下载新样式。
答案 2 :(得分:0)
仅指示浏览器在页面加载时加载资产...这就是它的工作方式。您可以轮询或使用任何形式的浏览器推送来检测后端更改,然后强制用户刷新其浏览器。
这不是缓存问题,不是浏览器问题……只是您掌握的信息可能已经过时了。您将不得不使用它或创建解决方法。
将其视为您公司咖啡机旁的日历,该日历在本周六有一个“聚会”活动。您看到了,奔向您的同事告诉他们这个好消息。同时,在日历上写事件的人意识到他犯了一个错误,并将事件更改为下一个星期六。您没有这些新信息,因此只要您不去喝咖啡,就会为您的同事提供错误的信息。知道更改的唯一方法是,有人会比您再去喝杯咖啡早通知您吗……例如,在日历上写活动的人会向所有人发送电子邮件,对自己的错误和聚会表示歉意定于下周六。