Blazor WebAssembly无法识别gRPC Web调用响应问题排查
Blazor WASM调用gRPC服务时RpcException被转为Cancelled异常的解决方法
在.NET Aspire微服务架构中,Blazor WebAssembly应用调用gRPC服务时,服务端抛出带NotFound状态的RpcException,但客户端未进入对应异常处理分支,反而抛出Cancelled异常,提示"No grpc-status found on response"。尽管浏览器网络面板显示响应头包含正确的Grpc-Status:5和Grpc-Message:Not Found,但客户端无法识别这些状态信息。
解决步骤
1. 更新服务端CORS配置,暴露gRPC响应头
在gRPC服务的Program.cs中修改CORS策略,明确添加grpc-status和grpc-message到暴露头列表:
builder.Services.AddCors(options => { options.AddPolicy("GrpcCorsPolicy", policy => { policy.WithOrigins("https://localhost:5001") // 替换为Blazor应用实际地址 .AllowAnyMethod() .AllowAnyHeader() .WithExposedHeaders("grpc-status", "grpc-message"); // 核心配置:暴露gRPC自定义头 }); }); // 确保在路由中间件之后启用CORS app.UseCors("GrpcCorsPolicy");
2. 确认服务端启用gRPC-Web支持
gRPC服务必须启用gRPC-Web才能与Blazor WASM客户端通信:
// 映射gRPC服务时启用GrpcWeb app.MapGrpcService<SmsService>().EnableGrpcWeb();
3. 验证客户端gRPC通道配置
客户端已正确配置GrpcWebHandler,无需修改,但需确认地址和实例注册无误:
builder.Services.AddSingleton(_ => { HttpClient httpClient = new(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler())) { BaseAddress = new("https://localhost:5244") }; GrpcChannel channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new() { HttpClient = httpClient }); return new SmsProto.SmsProtoClient(channel); });
原因说明
浏览器同源策略限制了JavaScript可读取的响应头范围,默认仅允许标准头(如Cache-Control、Content-Type)。grpc-status和grpc-message属于自定义头,必须通过Access-Control-Expose-Headers明确告知浏览器允许客户端代码读取。若未配置该项,即使服务端返回了这些头,客户端gRPC库也无法获取,从而错误将响应判定为"取消"状态,抛出Cancelled类型的RpcException。
内容的提问来源于stack exchange,提问作者Matin
相关产品推荐
相关产品推荐

