You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor交互式Web应用页面初始加载后重复刷新引发异常

问题诊断与解决

核心原因

你遇到的问题本质是Blazor InteractiveAuto渲染模式的双阶段渲染特性,加上Singleton服务的跨实例状态不共享导致的:

  1. 首次加载时,页面先在服务器端完成SSR渲染:此时服务器端的Singleton StateManagementService 实例会加载Games数据,页面短暂显示游戏标题。
  2. 随后客户端Blazor应用启动(hydration过程):客户端会创建一个全新的StateManagementService实例(Singleton在客户端是独立于服务器端的实例),导致Games变为null,触发客户端再次调用API,若此时存在跨域配置问题或API访问限制,就会抛出Failed to fetch异常。
  3. 组件代码存在笔误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:05:10