Blazor交互式Web应用页面初始加载后重复刷新引发异常
问题诊断与解决
核心原因
你遇到的问题本质是Blazor InteractiveAuto渲染模式的双阶段渲染特性,加上Singleton服务的跨实例状态不共享导致的:
- 首次加载时,页面先在服务器端完成SSR渲染:此时服务器端的Singleton
StateManagementService实例会加载Games数据,页面短暂显示游戏标题。 - 随后客户端Blazor应用启动(hydration过程):客户端会创建一个全新的
StateManagementService实例(Singleton在客户端是独立于服务器端的实例),导致Games变为null,触发客户端再次调用API,若此时存在跨域配置问题或API访问限制,就会抛出Failed to fetch异常。 - 组件代码存在笔误:
StateManagementService.Game.First().Title应为StateManagementService.Games.First().Title,少了复数后缀s。
具体解决方案
1. 用PersistentComponentState传递服务器端数据到客户端
这是适配InteractiveAuto模式的最优方案,避免重复API请求和状态不一致:
@inject PersistentComponentState PersistentComponentState // 保留原有注入项 @code { private PersistentComponentStateSubscription? _subscription; private bool _hasLoadedState; protected override async Task OnInitializedAsync() { // 客户端hydration时,直接读取服务器端预存的数据 if (PersistentComponentState.TryTakeFromJson<List<Game>>("Games", out var savedGames)) { StateManagementService.Games = savedGames; _hasLoadedState = true; return; } // 服务器端渲染时,加载数据并持久化到客户端可读取的状态中 try { if (StateManagementService.Games is null) { StateManagementService.Games = await GameAPIClient.GetAllGames(); PersistentComponentState.PersistAsJson("Games", StateManagementService.Games); } } catch (Exception ex) { Console.WriteLine($"Error fetching games: {ex.Message}"); } } // 组件销毁时取消状态订阅 public void Dispose() { _subscription?.Dispose(); } }
2. 调整服务注册范围(可选)
若你的状态不需要全局共享,可将StateManagementService从Singleton改为Scoped:
// Program.cs中修改服务注册 builder.Services.AddScoped<StateManagementService>();
注:Scoped在服务器端是每个请求一个实例,客户端是每个浏览器会话一个实例,适合用户级状态存储。
3. 修复代码笔误
将组件中的错误代码:
<p>@StateManagementService.Game.First().Title;</p>
改为:
<p>@StateManagementService.Games.First().Title</p>
(同时移除多余的分号)
4. 排查API跨域问题
若客户端仍出现Failed to fetch异常,检查API的CORS配置,确保允许Blazor应用域名访问:
在API的Program.cs中添加:
builder.Services.AddCors(options => { options.AddPolicy("AllowBlazorApp", policy => { policy.WithOrigins("https://你的Blazor应用域名") .AllowAnyHeader() .AllowAnyMethod(); }); }); // 在app.UseRouting()之后启用CORS app.UseCors("AllowBlazorApp");
内容的提问来源于stack exchange,提问作者HarrisonWD
相关产品推荐
相关产品推荐

