CORS 策略已阻止对提取的访问 - Blazor Client Web Assembly

Access to fetch has been blocked by CORS Policy - Blazor Client Web Assembly

我有一个 Blazor Web 程序集,它从构建在 ASP.NET 核心上的外部 API 获取,我无权访问。我可以执行 get 请求,但不能执行 post 请求。当我这样做时,出现以下错误。

Access to fetch at 'http://external:9000/User/Create' from origin 'http://localhost:56138' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

api 的作者确认他在启动时启用了 cors 以允许任何 header,并且还建议我也这样做,但这并没有解决问题。我从调试器确认我正在发送端点所需的正确数据格式,并且我也在与 Web 服务相同的 http 方案上 运行。

这是program.cs

中的客户端配置
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://external:9000/") });
builder.Services.AddCors(policy =>
{
   policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());
   });

我就是这样post

var dataJson = JsonConvert.SerializeObject(application);
var stringContent = new StringContent(dataJson, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"User/Create", stringContent);

我读到这是 blazor 程序集的一个常见问题,我不完全确定我读到的内容。我目前正在尝试将项目移动到 blazor 服务器以查看它是否可以工作,但我更喜欢它在 web assembly 上。

builder.Services.AddCors(policy =>
{
   policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());
   });

此配置应在服务器上完成,而不是您的服务器,而是外部 API 的服务器。你在这方面什么都不做,除了在那个网络上调用端点 Api.

The author of the api confirms they enabled cors to allow any header in his startup

如果是这样,请向他们询问验证码...

and also suggested I do the same but this did not fix the issue.

你什么都不做。

解决方案:

AS CORS 是浏览器强制执行的 JavaScript 安全功能,您可以通过调用您的服务器代码来绕过它,您从中执行对该 Web Api 端点的调用,然后returns 它返回到您的 WebAssembly 前端。尽可能多地使用异步代码。

根据评论更新

Are you saying I should have two projects, the server and the client under one solution? The server calls the calls the external api, then passes it to the client. Is this what your last suggestion is?

如果您使用托管的 WebAssembly Blazor 应用程序,其中托管服务器包含 Web Api 控制器,那么您应该公开可以从 WebAssembly 前端调用的端点。这些端点中的代码应执行对外部 Web Api 的 HTTP 调用,并将从外部 Web Api.

接收到的数据传回 WebAssembly 调用方法

注意:如果您没有这样的控制器(它们是由Visual Studio默认创建的),您可以自己将它们添加到服务器项目中。

如果您已经创建了一个 Web Api 项目而不是那些控制器,那么请从您的 Web Api 项目中公开必要的端点。请注意,只要您提供正确的 Url.

,您的 Web Api 项目是否驻留在 WebAssembly 前端的同一解决方案中都没有关系。

如果您单独使用 WebAssembly Blazor 应用程序;也就是说,默认安装不会创建服务器项目,您需要创建一个 Web Api 项目并使用它,除非您已经创建了一个。