Angular Service Worker和index.html缓存

Zyg*_*tas 6 caching cache-control service-worker angular angular-service-worker

尽管有类似的帖子,但是如果index.html应该使用Cache-Control标头来缓存,我找不到明确的答案。

纠正我,如果我错了,但现在我回来Cache-Control: no-storeindex.html,以避免散失配误差进入降级模式哪支部队服务工作人员。

我认为,如果index.html已将Cache-Control: max-age=3600其缓存在CDN服务器上,并且该应用程序将在缓存过期之前进行更新,ngsw.json则与脚本文件相比,该文件将返回不同的文件哈希值,其中包含的index.html坏消息将会发生。对?

另外,为了清楚起见,我注意到有些人添加index.htmlngsw-config.json,这也没有意义,因为它index.html是在服务工作者之前加载的。

小智 4

默认情况下,包含index.html。如果您不将其包含在清单中,那么它就不会成为散列和检查的文件的一部分。如果它不在清单中(以及随后的 ngsw.json),则对 index.html 的更改不会触发 Service Worker 中的事件。当然,当您下次加载/刷新站点时,它将获取新的index.html。

如果您从 CDN 中提供 index.html,那么它可能是您在上次部署中构建的发行版的一部分。应正确计算。如果您的文件与 ngsw.json 中的哈希值不匹配,那么上面突出显示的区域对于了解这一点非常重要。如果出于某种原因,您在修改 index.html 时未更新整个发行版,则 Service Worker 将假定该文件已损坏。它会再试一次;由于该文件与 ngsw.json 中的哈希不匹配,SW 将假定第二次尝试已损坏并关闭。

就我而言,这是因为应用程序包含构建期间留下的令牌,这些令牌在发布管道中被替换为 Azure 资源密钥。当应用程序构建时,哈希值是正确的。在该版本中,运行令牌替换后,我的 main*.js 文件不再与其在 ngsw.json 中的哈希值一致。我选择修复它的方法是添加一个 powershell 步骤并重新计算哈希值。需要注意的是,虽然实际的文件名具有唯一的哈希值?嵌入代码后,您无需更正该代码即可使 Service Worker 正常工作。文件名/哈希键/值对必须指向有效文件,并且该文件的 SHA1 哈希必须与 ngsw.json 中的内容匹配。我编写的用于对哈希值进行编译后验证/更正的脚本如下。如果您有一些独立于整个发行版更新 index.html 的进程,请使用此脚本更新 ngsw.json 并将其包含在您的 index.html 推送中。

笔记:

  • 脚本接受 3 个参数。如果未通过,则假定:
    • 该脚本正在从角度项目的根运行
    • 工作目录是"./dist"(要检查的脚本所在的位置)
    • 输入路径是"<working_dir>/ngsw.json"
    • 输出路径是"<working_dir>/ngsw_out.json"
  • 如果要修改文件,请确保指定相同的输入路径和输出路径
  • 如果将其放入 AzDO,则需要选中“使用 Powershell Core”复选框。

Powershell 脚本开始:

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."
}
Run Code Online (Sandbox Code Playgroud)