.NET 10 Blazor Web App配置PWA时的资源校验失败问题
Blazor Web App手动添加PWA后的SRI校验失败问题解决及离线方案建议
一、当前操作的错误点
你手动从独立Blazor WASM PWA复制资源和配置的方式,未适配**托管式Blazor Web App(全局WASM模式)**的资源打包逻辑:
- 独立PWA的
service-worker-assets.js适配的是独立项目的资源生成规则,但托管式项目发布时会自动给静态资源(如CSS)添加哈希指纹,你手动复制的旧文件仍保留未指纹的文件名,导致SRI校验不匹配。 - Client项目的csproj配置未启用SDK自动生成带指纹的资源清单逻辑,而是依赖手动复制的文件,造成资源列表与实际发布文件不一致。
二、修复步骤
1. 修正Client项目的csproj配置
更新PWATest.Client.csproj,添加以下关键配置,让.NET SDK自动生成正确的资源清单:
<PropertyGroup> <!-- 保留原有配置 --> <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest> <ServiceWorker>wwwroot/service-worker.js</ServiceWorker> </PropertyGroup> <ItemGroup> <ServiceWorkerAsset Include="wwwroot/**/*" Exclude="wwwroot/service-worker.js;wwwroot/service-worker-assets.js" /> </ItemGroup>
该配置会让SDK在发布时自动扫描所有静态资源,生成带指纹的资源列表到service-worker-assets.js,无需手动维护。
2. 替换服务工作者文件
删除从独立PWA复制的service-worker.js,使用适配托管式项目的版本,自动引用SDK生成的资源清单:
import { registerRoute } from 'workbox-routing'; import { StaleWhileRevalidate, CacheFirst } from 'workbox-strategies'; import { CacheableResponsePlugin } from 'workbox-cacheable-response'; import { precacheAndRoute } from 'workbox-precaching'; // 自动预缓存SDK生成的带指纹资源 precacheAndRoute(self.__WB_MANIFEST); // 可选:缓存API请求(按需调整策略) registerRoute( ({ url }) => url.pathname.startsWith('/api/'), new StaleWhileRevalidate({ cacheName: 'api-cache', plugins: [new CacheableResponsePlugin({ statuses: [200] })], }) ); // 可选:缓存图片、字体等静态资源 registerRoute( ({ request }) => request.destination === 'image' || request.destination === 'font', new CacheFirst({ cacheName: 'static-resources', plugins: [new CacheableResponsePlugin({ statuses: [200] })], }) );
3. 移除手动复制的service-worker-assets.js
该文件由SDK自动生成,手动复制的旧文件会干扰正确的资源清单生成,直接删除即可。
4. 确认App.razor的注册逻辑
确保App.razor中的manifest引用和服务工作者注册脚本正确:
<head> <!-- 保留原有头部内容 --> <link rel="manifest" href="manifest.json" /> <link rel="apple-touch-icon" href="icon-512.png" sizes="512x512" /> </head> <body> <!-- 组件内容 --> <script> if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('service-worker.js') .then(reg => console.log('Service Worker registered:', reg)) .catch(err => console.error('Service Worker注册失败:', err)); }); } </script> </body>
5. 重新发布项目
清理旧的发布目录,执行发布命令:
dotnet publish -c Release
此时生成的service-worker-assets.js会包含带指纹的CSS文件条目,SRI校验即可通过。
三、更合适的离线功能实现方案
1. 直接使用独立Blazor WASM PWA项目
如果你的场景是“在线为主,离线可填表单”,直接创建独立PWA项目更省心,命令如下:
dotnet new blazorwasm -o PWATest -f net10.0 -p true
该项目默认已配置好PWA、资源指纹、服务工作者,无需手动调整,只需配置后端API地址即可支持离线表单+联网同步。
2. 用IndexedDB存储离线表单数据
PWA缓存主要用于静态资源,用户生成的表单数据建议用IndexedDB存储:
- 离线时,将表单数据写入IndexedDB
- 联网时,读取IndexedDB中的待同步数据,批量提交到后端,成功后删除本地数据
可使用Blazor第三方库(如Blazor.IndexedDB)简化操作,比依赖缓存更可靠。
3. 结合Background Sync API实现自动同步
为提升体验,可搭配Service Worker的Background Sync API:
- 离线提交表单时,保存数据到IndexedDB并注册Sync任务
- 设备联网后,Service Worker自动触发Sync事件,完成数据提交
- 提交成功后清理本地数据和Sync任务
内容的提问来源于stack exchange,提问作者Tobias
相关产品推荐
相关产品推荐

