我创建了一个新的 Blazor PWA WebAssembly(最新版本默认模板)项目,并将其部署在 Windows Server 中的 IIS 中以尝试 PWA。
安装了最后一个 .NET Core 托管捆绑包。
发布后,我在Microsoft Docs中运行脚本来重命名dll文件:
dir .\_framework\_bin | rename-item -NewName { $_.name -replace ".dll\b",".bin" } ((Get-Content .\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content .\_framework\blazor.boot.json
ServiceWorker 也重命名代码:
((Get-Content .\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content .\service-worker-assets.js
然后我按照文档所述删除了压缩文件:
wwwroot\service-worker-assets.js.br
wwwroot\service-worker-assets.js.gz
wwwroot\_framework\blazor.boot.json.br
wwwroot\_framework\blazor.boot.json.gz
但是当我加载应用程序时仍然出现错误:
我在这里错过了什么?
我猜这与哈希值和重命名有关,但在 Blazor 的 Github 问题中找不到任何解决方案。
由于修改了 blazor.boot.json 文件,完整性检查失败。 service-worker-assets.js 包含文件列表及其在发布时计算的完整性哈希值。 您可以使用 Bash/PowerShell 手动重新计算哈希值,因为您使用的是 IIS,我将提供用于解决类似问题的 PowerShell 脚本:
# make sure you're in the wwwroot folder of the published application
$JsFileContent = Get-Content -Path service-worker-assets.js -Raw
# remove JavaScript from contents so it can be interpreted as JSON
$Json = $JsFileContent.Replace("self.assetsManifest = ", "").Replace(";", "") | ConvertFrom-Json
# grab the assets JSON array
$Assets = $Json.assets
foreach ($Asset in $Assets) {
$OldHash = $Asset.hash
$Path = $Asset.url
$Signature = Get-FileHash -Path $Path -Algorithm SHA256
$SignatureBytes = [byte[]] -split ($Signature.Hash -replace '..', '0x$& ')
$SignatureBase64 = [System.Convert]::ToBase64String($SignatureBytes)
$NewHash = "sha256-$SignatureBase64"
If ($OldHash -ne $NewHash) {
Write-Host "Updating hash for $Path from $OldHash to $NewHash"
# slashes are escaped in the js-file, but PowerShell unescapes them automatically,
# we need to re-escape them
$OldHash = $OldHash.Replace("/", "\/")
$NewHash = $NewHash.Replace("/", "\/")
$JsFileContent = $JsFileContent.Replace("""$OldHash""", """$NewHash""")
}
}
Set-Content -Path service-worker-assets.js -Value $JsFileContent -NoNewline
此脚本会迭代 service-worker-assets.js 中列出的所有文件,计算每个文件的新哈希值,并更新 JavaScript 文件中的哈希值(如果不同)。 您必须使用已发布的 wwwroot 文件夹作为当前工作目录来执行脚本。
我在博客上更详细地描述了这一点:修复 Blazor WebAssembly PWA 完整性检查
完整性哈希是根据未压缩的文件计算的。问题似乎是 brotli 和 gzipped 版本很可能被缓存,虽然未压缩版本是使用 SDK 更新的,但压缩版本会在更新之前被重复使用。由于如果客户端接受(浏览器会),Kestler 和 IIS 都会尝试提供压缩版本,因此您将获得旧版本,而哈希值将用于新版本,从而导致完整性检查错误。
不幸的是,任何本地更改或修复都将是暂时的。
解决这个问题的唯一方法似乎是在发布后重新压缩它们。评论中有一些这方面的好建议。
我制作了一个金块发布的工具(可以作为项目的一部分安装或全局安装)来解决这个问题:
https://github.com/zorgoz/PreCompress
向
.csproj
文件添加适当的部分将自动导致在发布管道末尾重新压缩所有必要的文件,而无需修改其他脚本。