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
相关产品推荐
相关产品推荐

