虽然有类似的帖子,但我找不到明确的答案是否应使用index.html
标头缓存Cache-Control
。
如果我错了,请纠正我,但现在我将Cache-Control: no-store
返回index.html
以避免散列不匹配错误,该错误会迫使服务工作者进入降级模式。
我认为,如果将具有index.html
的{{1}}缓存在CDN服务器上,并且该应用将在缓存过期之前进行更新,那么Cache-Control: max-age=3600
将返回与脚本文件相比不同的文件哈希, ngsw.json
中包含的内容,可能会发生不良情况。对吧?
为了清楚起见,我注意到有些人将index.html
添加到index.html
,这也没有意义,因为已加载ngsw-config.json
在服务人员之前。
答案 0 :(得分:1)
默认情况下,包含index.html。如果您未将其包含在清单中,则它不会成为散列和检查文件的一部分。如果它不在清单(以及随后的ngsw.json)中,则对index.html的更改不会触发服务工作程序中的事件。当然,下次加载/刷新该网站时,它将选择新的index.html。
如果您要通过CDN提供index.html,那么大概是您在上次部署中构建的发行版的一部分。应该正确计算。上面突出显示的区域对于理解ngsw.json中的哈希值不匹配的文件很重要。如果由于某种原因在修改index.html而不更新整个发行版,则Service Worker将认为该文件已损坏。再试一次;由于该文件与ngsw.json中的哈希不匹配,因此SW会假定第二次尝试已损坏并关闭。
在我的情况下,这是因为应用程序包含在生成期间遗留的令牌,这些令牌在发布管道中已被Azure资源密钥替换。构建应用程序时,哈希值是正确的。在发行版中,运行令牌替换后,我的main * .js文件不再与ngsw.json中的哈希值保持一致。我选择修复它的方法是添加一个powershell步骤并重新计算哈希值。重要的是要注意,尽管实际的文件名具有唯一的哈希值?内嵌代码,您无需为服务工作者进行更正。文件名/哈希键/值对必须指向有效文件,并且该文件的SHA1哈希必须与ngsw.json中的内容匹配。我编写的用于对哈希进行编译后验证/更正的脚本如下。如果您有一些独立于整个发行版来更新index.html的过程,请使用此脚本来更新ngsw.json并将其包含在index.html push中。
注释:
"./dist"
(要检查的脚本所在的位置)"<working_dir>/ngsw.json"
"<working_dir>/ngsw_out.json"
param([string]$working_path = "./dist"
, [string]$input_file_path = "$working_path/ngsw.json"
, [string]$output_file_path = "$working_path/ngsw_out.json")
"Checking for existence of hash script..."
$fileExists = Test-Path -Path $input_file_path
if ($fileExists) {
"Service Worker present. Beginning hash reconciliation."
""
$files_to_calc = @()
$ngsw_json = (Get-Content $input_file_path -Raw) | ConvertFrom-Json
"-----------------------------------------"
"Getting list of javascript files to check"
"-----------------------------------------"
$found_count = 0
for ($idx = 0; $idx -lt $ngsw_json.hashtable.psobject.properties.name.count; $idx++) {
$current_file = $ngsw_json.hashtable.psobject.properties.name[$idx]
if ($current_file.Contains(".js")) {
$files_to_calc += $current_file
" File {$idx} $($files_to_calc[-1]) found."
$found_count++
}
}
"---------------------------------------"
"$($files_to_calc.count) files to check."
"---------------------------------------"
$replaced_count = 0
$files_to_calc | ForEach-Object {
$new_hash_value = (Get-FileHash -Algorithm SHA1 "$($working_path)$_").Hash.ToLower()
$current_hash_value = $ngsw_json.hashTable.$_
$current_index = [array]::IndexOf($ngsw_json.hashTable.psobject.properties.name, $_)
$replaced = $false
if ($ngsw_json.hashTable.$_ -ne $new_hash_value) {
$ngsw_json.hashTable.$_ = "$new_hash_value"
$replaced = $true
$replaced_count++
}
"$($replaced ? '** ' : ' '){$current_index}:$_ --- Current Value: " +
"$($current_hash_value.substring(0, 8))... New Value: " +
"$($new_hash_value.substring(0, 8))..."
}
""
"--> Replaced $replaced_count hash values"
$ngsw_json | ConvertTo-Json -depth 32 | set-content "$output_file_path"
}
else {
"Service Worker missing. Skipping."
}
答案 1 :(得分:0)
我不是这方面的专家,但我可以肯定,以下链接将帮助您解决疑问。
https://angular.io/guide/service-worker-getting-started#whats-being-cached
正在缓存什么?
请注意,浏览器呈现此应用程序所需的所有文件都已缓存。设置ngsw-config.json样板配置以缓存CLI使用的特定资源:
index.html。
favicon.ico。
构建工件(JS和CSS包)。
资产下的任何东西。
直接在已配置的outputPath(默认为./dist//)或resourcesOutputPath下的图像和字体。查看ng build 有关这些选项的更多信息。
下面的链接包含有关Service worker and caching of app resources的信息。我希望您从中了解App versions,Update checks和Resource integrity。
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()的新捆绑包是无效的。
在延迟加载模块时,此文件完整性尤为重要。 JS捆绑包可能引用许多惰性块,并且这些惰性块的文件名对于特定的应用程序版本而言是唯一的。如果正在运行的版本X的应用程序尝试加载惰性块,但是服务器已更新至版本X + 1,则惰性加载操作将失败。
应用程序的版本标识符由所有资源的内容确定,如果其中任何一个发生更改,它就会更改。实际上,版本由ngsw.json文件的内容确定,其中包括所有已知内容的哈希值。如果任何缓存的文件发生更改,则ngsw.json中的文件哈希将发生更改,从而使Angular服务工作人员将活动文件集视为新版本。
借助Angular服务工作者的版本控制行为,应用服务器可以确保Angular应用始终具有一致的文件集。
更新检查
每次用户打开或刷新应用程序时,Angular服务工作人员都会通过查找ngsw.json清单的更新来检查应用程序的更新。如果找到更新,则会自动下载并缓存该更新,并在下次加载应用程序时将其提供。
资源完整性
长缓存的潜在副作用之一是无意中缓存了无效资源。在普通的HTTP缓存中,硬刷新或缓存过期限制了缓存无效文件的负面影响。服务工作人员会忽略此类约束,并有效地长时间缓存整个应用程序。因此,至关重要的是服务人员必须获取正确的内容。
为确保资源完整性,Angular服务工作程序会验证其具有哈希值的所有资源的哈希值。通常,对于使用Angular CLI创建的应用程序来说,这就是dist目录中用户src / ngsw-config.json配置所涵盖的所有内容。
如果特定文件未通过验证,Angular服务工作人员将尝试使用“缓存无效” URL参数重新获取内容,以消除浏览器或中间缓存的影响。如果该内容也未通过验证,则服务工作者将认为该应用程序的整个版本无效,并停止提供该应用程序。如有必要,服务人员会进入一种安全模式,在该模式下,请求会回落到网络上,如果服务无效,损坏或过时的内容的风险很高,则选择不使用其缓存。
哈希不匹配的发生可能有多种原因:
答案 2 :(得分:0)
我认为您有必要了解Angular应用程序工作流程和Angular Service Worker运行时缓存机制。 所以我将在这里写下有关它们的信息。这将对您的理解有所帮助。
Angulars开始执行以下步骤。
- Angular以 main.ts 开头。
- 启动了Angular应用程序,并作为参数传递了 app.module.ts 。
- 然后Angular分析应用程序组件,读取在那里传递的设置,然后有SELECTOR 应用程序根。
- 现在,Angular可以处理 index.html 中的 app-root ,并且知道SELECTOR的规则。
- SELECTOR应该插入应用程序组件,并具有一些HTML代码-附加到他的模板-html组件。
Angular ServiceWorker
Angular CLI还包括在Angular应用程序根模块中, 服务工作者模块。 CLI还添加了一个名为 ngsw-config.json 的新配置文件,该文件用于配置 Angular Service Worker 运行时行为,并且随附了生成的文件 一些智能的默认值。这里有很多事情,所以让我们 逐步分解。该文件包含默认缓存 行为或 Angular Service Worker (针对 应用程序静态资产文件: index.html , CSS 和 JavaScript 捆绑包。
Angular Service Worker 可以将所有内容缓存在 浏览器缓存存储。这是基于Java的键/值缓存 与标准浏览器无关的机制 缓存控制机制,这两种机制可以分别使用。
“应用”部分下的文件就是应用:一个页面是 由 index.html 加上 CSS 以及 Js 捆绑包。这些文件对于应用程序的每个页面都是必需的,并且不能延迟加载。
对于这些文件,我们希望尽早缓存它们,然后 尽可能永久地保存,这就是 app缓存 配置。应用程序文件将被主动 由 Service Worker 下载并安装在后台, 这就是安装方式预取的意思。 服务 worker 不会等待服务器请求这些文件 应用程序,它将提前下载,然后 缓存,以便它可以下次请求它们。这是采用以下策略的好策略: 一起制作应用程序本身( index.html , CSS 和 Javascript 包),因为我们已经知道我们将一直需要它们。
index.html 取决于 index.js ,而 chunk.js 取决于jquery.js。 块是从浏览器缓存加载的。