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

Blazor访问localstorage时JavaScript互操作错误求助

解决方案

1. 在JWT拦截器中跳过预渲染/服务器端环境的Token读取

预渲染是在服务器端执行的,此时没有浏览器LocalStorage环境,必须在拦截器中判断当前环境,避免执行JS互操作:

public class JwtAuthenticationHeaderHandler : DelegatingHandler
{
    private readonly ILocalStorageService _localStorage;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public JwtAuthenticationHeaderHandler(ILocalStorageService localStorage, IHttpContextAccessor httpContextAccessor)
    {
        _localStorage = localStorage;
        _httpContextAccessor = httpContextAccessor;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // 服务器端/预渲染阶段,直接转发请求不处理Token
        if (_httpContextAccessor.HttpContext != null)
        {
            return await base.SendAsync(request, cancellationToken);
        }

        // 客户端环境下正常读取LocalStorage并添加请求头
        var token = await _localStorage.GetAsync<string>(StorageConstants.Local.UserId);
        if (!string.IsNullOrEmpty(token))
        {
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
        }

        return await base.SendAsync(request, cancellationToken);
    }
}

需在Program.cs中注册依赖:

builder.Services.AddHttpContextAccessor();

2. 确保API调用仅在客户端渲染阶段触发

即使在OnAfterRenderAsync中执行逻辑,也要加上预渲染判断,避免服务器端触发API请求:

@inject NavigationManager NavigationManager

@code {
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // 仅在客户端首次渲染时执行API调用
        if (firstRender && !NavigationManager.IsPreRendering)
        {
            await LoadDataFromApi();
        }
    }

    private async Task LoadDataFromApi()
    {
        // 你的API调用逻辑
    }
}

NavigationManager.IsPreRendering(.NET 6+支持)可直接判断是否处于预渲染状态。

3. 预渲染阶段改用服务器端身份(可选)

如果需要预渲染时也能调用API,不要依赖客户端LocalStorage,改用服务器端可获取的身份信息(如Cookie):

if (_httpContextAccessor.HttpContext != null)
{
    // 从服务器端Cookie读取Token
    var serverToken = _httpContextAccessor.HttpContext.Request.Cookies["JwtToken"];
    if (!string.IsNullOrEmpty(serverToken))
    {
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", serverToken);
    }
    return await base.SendAsync(request, cancellationToken);
}

需在登录时将Token同时存入Cookie和LocalStorage,保证服务器端可读取。

4. 禁用特定组件的预渲染

若组件完全依赖客户端JS功能,可直接禁用预渲染,强制客户端渲染:

在组件Razor文件中添加:

@attribute [RenderModeInteractiveWebAssembly]

或在路由注册时全局配置:

app.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies(typeof(YourComponent).Assembly);

内容的提问来源于stack exchange,提问作者ACristian24

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:40:14