Blazor WebAssembly(托管)应用转为PWA后本地调试无功能、点击按钮无响应问题咨询
咱先捋清楚Blazor WASM托管项目里PWA在本地和生产环境的默认差异,这事儿主要是这几个原因:
Service Worker的版本不一样
本地调试时,项目用的是service-worker.js——这是个开发专用的简化版,逻辑特别简单,就做个跳过等待和接管客户端的操作,完全不会缓存任何静态资源。而部署到Azure后,系统会自动切换成service-worker.published.js,这个版本是基于Workbox做的,有完整的资源缓存策略,能满足PWA的核心特性(比如离线访问、添加到手机主屏)。你可以直接打开这两个文件对比下内容,一看就明白区别了。VS2019调试的浏览器限制
本地调试时,要么VS会偷偷给浏览器加限制,要么你开着开发者工具的时候,浏览器本身会跳过service worker的缓存逻辑——毕竟调试的时候总缓存旧资源也影响开发。你可以试试关掉开发者工具再刷新页面,或者去浏览器的Application面板里手动注册service worker,清空缓存后再测试。开发模式的默认配置
Blazor在开发环境(也就是ASPNETCORE_ENVIRONMENT=Development)下,默认就不会启用PWA的完整缓存功能,怕的就是缓存旧代码影响你调试。如果非要在本地看PWA效果,可以手动把环境变量改成Production,或者修改service worker的配置。
当PWA正常跑起来(也就是用了发布版的service worker),出现按钮没反应、SignalR和数据库交互失效的问题,十有八九是缓存策略搞错了,把动态API请求或者SignalR连接给拦截/缓存了,或者service worker没正确转发请求。
给你几个排查方向:
Workbox缓存策略误拦了API请求
service-worker.published.js默认会缓存静态资源,但如果你的API路径(比如/api/xxx)没被排除在外,Workbox可能会把API请求也给缓存了,或者直接拦截住不转发到服务器。
解决办法很简单,修改这个文件,给API路由加个特殊规则:workbox.routing.registerRoute( ({url}) => url.pathname.startsWith('/api/'), new workbox.strategies.NetworkFirst() // 优先用网络请求,真断网了再用缓存(如果需要的话) );要是完全不想缓存API请求,就用
NetworkOnly策略,强制走网络。SignalR连接被service worker干扰了
SignalR用的WebSockets或者长轮询,很容易被service worker的缓存逻辑搞乱。你得确保service worker不对SignalR的hub路径做缓存,直接转发到服务器。比如你的hub是/chatHub,就加这么一段:workbox.routing.registerRoute( ({url}) => url.pathname.startsWith('/chatHub'), new workbox.strategies.NetworkOnly() // 必须走网络,绝对不能缓存 );旧代码缓存导致逻辑不兼容
PWA缓存了旧的客户端代码后,可能和服务器端的API或者SignalR逻辑不匹配——比如服务器端接口改了,但客户端还是旧代码,自然点按钮没反应。这时候你可以修改manifest.json里的version字段,或者在service worker里加更新逻辑,让新版本部署时自动触发客户端更新。本地强制用发布版service worker的状态问题
要是你在本地强行启用了发布版的service worker,可能会因为本地HTTPS的小问题(虽然VS2019本地调试是HTTPS,但有时候证书会有小问题),或者service worker注册状态异常,导致请求发不出去。这时候去浏览器的Application面板,删掉PWA的缓存数据,重新注册service worker再测。
内容的提问来源于stack exchange,提问作者T0bi

