虽然我不是一个专家,但我相当确定以下链接可以帮助你解决疑问。
https://angular.io/guide/service-worker-getting-started#whats-being-cached
什么被缓存了?
请注意,浏览器渲染此应用程序所需的所有文件都已被缓存。ngsw-config.json样板配置已设置为缓存CLI使用的特定资源:
以下链接提供了关于服务工作者和应用资源缓存的信息。我希望您阅读应用版本, 更新检查和资源完整性的相关内容。
https://angular.io/guide/service-worker-devops#service-worker-and-caching-of-app-resources
我也将这三个部分的内容粘贴在这里,以避免这个答案成为“仅链接答案”。
应用程序版本
在 Angular 服务工作者的上下文中,“版本”是表示特定 Angular 应用程序构建的资源集合。每当部署应用程序的新构建时,服务工作者将该构建视为应用程序的新版本。即使只更新了单个文件,这也是正确的。在任何给定时间,服务工作者可能会在其缓存中拥有多个应用程序版本,并且可以同时提供它们。有关更多信息,请参见下面的应用程序选项卡部分。
为了保持应用程序的完整性,Angular服务工作器会将所有文件分组到一个版本中。通常,分组到一个版本的文件包括HTML、JS和CSS文件。将这些文件分组是至关重要的,因为HTML、JS和CSS文件经常相互引用并依赖于特定的内容。例如,一个index.html文件可能有一个标签,引用bundle.js,并尝试从该脚本内部调用startApp()函数。每次提供此版本的index.html时,必须与之一起提供相应的bundle.js。例如,假设startApp()函数在两个文件中都被重命名为runApp()。在这种情况下,不能用调用startApp()的旧index.html和定义了runApp()的新bundle一起提供。
当惰性加载模块时,文件完整性尤其重要。一个JS捆绑包可能引用许多惰性块,而惰性块的文件名对于应用程序的特定构建是唯一的。如果运行版本X的应用程序尝试加载惰性块,但服务器已经更新到版本X + 1,那么惰性加载操作将失败。
应用程序的版本标识符是由所有资源内容确定的,如果它们中的任何一个发生更改,它也会发生变化。在实践中,版本是由ngsw.json文件的内容确定的,它包括所有已知内容的哈希值。如果缓存的文件中有任何更改,则该文件的哈希值将在ngsw.json中更改,导致Angular服务工作器将活动文件集视为新版本。
通过Angular服务工作器的版本控制行为,应用程序服务器可以确保Angular应用始终具有一致的文件集。
更新检查
每次用户打开或刷新应用程序时,Angular服务工作者都会通过查找ngsw.json清单的更新来检查应用程序的更新。如果找到更新,则会自动下载和缓存,并在下次加载应用程序时提供服务。
资源完整性
长时间缓存的潜在副作用之一是无意中缓存无效资源。在普通HTTP缓存中,硬刷新或缓存过期限制了缓存无效文件的负面影响。服务工作者忽略这种约束,并有效地长时间缓存整个应用程序。因此,确保服务工作者获得正确的内容非常重要。
为确保资源完整性,Angular服务工作者验证其具有哈希值的所有资源的哈希值。通常对于使用Angular CLI创建的应用程序,这是用户src/ngsw-config.json配置覆盖的dist目录中的所有内容。
如果特定文件未通过验证,则Angular服务工作者尝试使用“缓存破坏”URL参数重新获取内容,以消除浏览器或中间缓存的影响。如果该内容也未通过验证,则服务工作者认为整个应用程序版本无效,并停止提供应用程序。如有必要,服务工作者进入安全模式,其中请求回退到网络,选择不使用其缓存,如果提供无效、损坏或过时的内容的风险很高。
哈希不匹配可能出现各种原因:
- 源服务器和最终用户之间的缓存层可能提供过时的内容。
- 非原子部署可能导致Angular服务工作者看到部分更新的内容。
- 构建过程中的错误可能导致更新的资源而没有更新ngsw.json。反之亦然,导致更新的ngsw.json而没有更新的资源。
Cache-Control: no-store
到ngsw.json
中?我想可能是你的ngsw.json
文件正在使用较旧的版本进行服务,如果这样做可以解决问题。如果有效,请尝试从index.html
中删除Cache-Control: no-store
。我认为这也应该有效,因为Angular的Service Worker使用缓存破坏器获取新资源。如果这有效,请告诉我,我会将其发布为答案。 - KrishnanCache-Control: no-store
的呢? - Willie