Blazor WASM调用PostAsJsonAsync报Failed to fetch如何解决
问题根因
Blazor WASM运行在浏览器沙箱中,完全受浏览器同源策略约束,你遇到的「GET正常、Postman调用正常、仅POST请求报Failed to fetch」是典型的后端CORS跨域配置错误导致的。
具体逻辑:
- 你POST请求发送的是
application/json格式的内容,不属于浏览器定义的简单请求范畴,浏览器会在正式发POST请求前,自动发送一个OPTIONS方法的预检请求,校验后端是否允许当前前端源的跨域调用、是否允许POST方法、是否允许对应请求头,只有预检通过才会发送真正的业务请求。 - Postman、服务端内部调用不受浏览器同源策略限制,不会触发预检流程,所以调用正常。
- 普通GET请求属于简单请求,不需要发送预检请求,所以你之前的GET接口能正常访问,不代表CORS配置是正确的。
解决步骤
1. 为WebAPI项目配置正确的CORS策略
注意配置顺序和写法,90%的CORS不生效都是配置顺序错了。以下是.NET 6+ 通用API/Minimal API项目的配置方式:
在Program.cs中,先在服务注册阶段(builder.Build()之前)添加CORS策略定义:
const string AllowBlazorWasmPolicy = "_allowBlazorWasm"; builder.Services.AddCors(options => { options.AddPolicy(AllowBlazorWasmPolicy, policy => { // 替换为你Blazor WASM项目实际运行的源地址,注意不要带末尾斜杠 policy.WithOrigins("http://localhost:5098", "https://localhost:7123") .AllowAnyHeader() .AllowAnyMethod(); // 如果接口需要携带Cookie、Authorization认证头,再加下面这行 // 注意:加了AllowCredentials就不能用AllowAnyOrigin,必须明确指定允许的源 // .AllowCredentials(); }); });
然后在中间件配置阶段,必须把CORS中间件放在UseAuthorization、MapControllers之前,否则配置不会生效:
var app = builder.Build(); // 其他中间件比如UseHttpsRedirection、UseStaticFiles可以放在CORS前面 app.UseCors(AllowBlazorWasmPolicy); // 位置不能错 app.UseAuthorization(); app.MapControllers(); app.Run();
2. 排查混合内容拦截问题
如果你的Blazor WASM运行在HTTPS协议下,接口地址写了HTTP开头的地址,浏览器会默认拦截混合内容请求,也会抛出"Failed to fetch"错误。开发阶段建议统一使用HTTPS地址调用接口,更推荐用相对路径(比如直接写"api/customers")配合开发代理,不用硬编码localhost端口,上线时也不需要修改接口地址。
3. 验证配置生效
重启后端服务后,打开浏览器开发者工具的「网络」面板,重新触发提交操作:
- 可以看到先发出一个OPTIONS方法的预检请求到你的POST接口地址,返回204状态码
- 预检通过后浏览器自动发出真正的POST请求,接口正常返回200状态码,错误消失
常见踩坑
- 不要自己在Controller里写Action处理OPTIONS请求,CORS中间件会自动完成预检响应,自己写反而容易冲突
- 不要使用
AllowAnyOrigin()+AllowCredentials()的组合,ASP.NET Core会直接阻止这个不安全的配置,要么去掉AllowCredentials,要么明确指定允许的源地址 - 如果你的后端加了自定义中间件、WAF或者反向代理(比如Nginx、IIS的URL重写),要确保OPTIONS请求不会被这些组件拦截,能正常到达CORS中间件
内容的提问来源于stack exchange,提问作者reiniX86
相关产品推荐
相关产品推荐

