CORS 策略已阻止访问 fetch - Blazor 客户端 Web 程序集

Posted

技术标签:

【中文标题】CORS 策略已阻止访问 fetch - Blazor 客户端 Web 程序集【英文标题】:Access to fetch has been blocked by CORS Policy - Blazor Client Web Assembly 【发布时间】:2021-04-27 16:56:35 【问题描述】:

我有一个 blazor Web 程序集,它从基于 ASP.NET Core 构建的外部 API 获取,但我无权访问。我可以执行获取请求,但无法执行发布请求。当我这样做时,我收到以下错误。

CORS 策略已阻止从源“http://localhost:56138”获取“http://external:9000/User/Create”的访问权限:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

api 的作者确认他启用了 cors 以允许在他的启动中使用任何标头,并建议我也这样做,但这并没有解决问题。我从调试器确认我正在发送端点所需的正确数据格式,并且我也在与 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());
   );

这就是我发帖的方式

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 程序集上使用它。

【问题讨论】:

在客户端使用.AddCors(...) 用处不大。看起来其他作者可能允许任何标题但不允许任何方法。问题出在服务器上。 但是如果你无法修复这个问题,Blazor Server 应该不会有这个问题。 @HenkHolterman 这正是我的想法。我只是绝望地添加它。 您可以编写自己的 API 层作为中间人。让您仍然可以使用 Blazor Wasm。 @HenkHolterman 我让它在 Blazor 服务器上运行。我想我会坚持下去。而且我不必担心应用程序无法在某些浏览器上运行,例如 Web 程序集给出的问题 【参考方案1】:
builder.Services.AddCors(policy =>

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

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

api 的作者确认他们启用了 cors 以允许他的启动中的任何标题

如果是这样,请向他们索取验证码...

并且还建议我这样做,但这并没有解决问题。

你什么都不做。

解决办法:

因为 CORS 是浏览器强制执行的 javascript 的一项安全功能,您可以通过调用您的服务器代码来规避它,您可以从该代码执行对该 Web Api 端点的调用,然后将其返回到您的 WebAssembly 前端。尽可能使用异步代码。

根据评论更新

你是说我应该有两个项目,一个解决方案下的服务器和客户端?服务器调用外部 api,然后将其传递给客户端。这是您最后的建议吗?

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

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

如果您已经创建了 Web Api 项目而不是那些控制器,请从您的 Web Api 项目中公开必要的端点。请注意,您的 Web Api 项目是否驻留在 WebAssembly 前端的相同解决方案中没有区别,只要您提供正确的 Url。

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

【讨论】:

你是说我应该有两个项目,一个解决方案下的服务器和客户端?服务器调用外部 api,然后将其传递给客户端。这是你最后的建议吗? 我已更新我的答案以反映您的评论。

以上是关于CORS 策略已阻止访问 fetch - Blazor 客户端 Web 程序集的主要内容,如果未能解决你的问题,请参考以下文章

CORS 策略已阻止对 XMLHttpRequest 的访问

CORS 策略已阻止从源对 X 的 XMLHttpRequest 的 CORS 访问

CORS策略已阻止从源''访问'apiurl'处的XMLHttpRequest [重复]

CORS 策略已阻止访问从源“http://localhost:3000”获取

访问 XMLHttpRequest 的问题已被 CORS 策略(Python/Angular)阻止

AngularJs——对 XMLHttpRequest 的访问已被 CORS 策略阻止 [重复]