【发布时间】:2021-02-27 16:13:41
【问题描述】:
我有一个 Blazor WASM 应用程序和一个 Web Api,供 Blzor 通过 HttpClient 调用。两个程序都在同一台机器上运行(也可以在生产环境中运行,这对于小型企业应用程序来说不应该是异国情调的!)。
从 Blazor 客户端调用 Web Api 会导致客户端 CORS 异常
CORS 政策已阻止从源“https://localhost:5001”获取“http://localhost:4040/”的访问权限:没有“Access-Control-Allow-Origin”标头出现在请求的资源。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
这是本案例的预期行为。
在我以前用 PHP 开发的一个具有相同客户端行为的 api 项目中,我可以通过简单地设置响应标头来绕过 CORS 异常,例如
$response = new Response;
$response->setState(false, $route->command);
...
header("Access-Control-Allow-Origin: *");
echo $response;
现在我想在我的 .net 5.0 Web Api 中使用它。我在互联网上找到了不同的文档来处理类似的问题
https://docs.microsoft.com/de-de/aspnet/core/security/cors?view=aspnetcore-5.0 https://www.c-sharpcorner.com/article/enabling-cors-in-asp-net-core-api-application/ https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.cors.infrastructure.corspolicybuilder.withorigins?view=aspnetcore-5.0
并在我的 api 中实现它
public class Startup {
//---------------------------------------------------------------------
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
//---------------------------------------------------------------------
public IConfiguration Configuration { get; }
//---------------------------------------------------------------------
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices
(
IServiceCollection services
)
=> services
.AddCors()
.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "api", Version = "v1"}) )
.AddControllers()
;
//---------------------------------------------------------------------
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure
(
IApplicationBuilder app,
IWebHostEnvironment env
)
=> app.
apply( _ =>
{
if (true) //(env.IsDevelopment())
{
app
.UseDeveloperExceptionPage()
.UseSwagger()
.UseSwaggerUI( c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "api v1") );
}
})
.UseCors( cors =>
cors
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed( _ => true )
.AllowCredentials()
)
.UseHttpsRedirection()
.UseRouting()
.UseAuthorization()
.UseEndpoints( e => e.MapControllers() )
;
//---------------------------------------------------------------------
}
甚至尝试在 ApiController 中设置响应头
[Route("/")]
[ApiController]
public sealed class ServertimeController : ControllerBase
{
//[EnableCors("AllowOrigin")]
[HttpGet]
public Servertime Get() {
Response.Headers.Add("Access-Control-Allow-Origin", "*");
Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT");
return servertime();
}
}
Blazor WASM 客户端看起来像
private async void onClick()
{
var response = await httpClient.GetFromJsonAsync<Servertime> ("http://localhost:4040");
message = response.servertime;
this.StateHasChanged();
}
但它仍然会导致客户端 CORS 异常。 为了绕过这个进行开发,我使用了浏览器扩展“CORS Unblock”,但这不是部署的选项。
避免 Blazor 客户端异常的正确方法是什么, 我错过了什么?
【问题讨论】:
-
在托管项目模板中,应用程序和 服务 都从同一端口运行,而不仅仅是同一台机器。在您的情况下,您使用的是两个不同的端口,就 CORS 而言,这与使用两台不同的机器没有什么不同。
-
您真的想将应用程序和 API 托管在不同的端口上吗?在这种情况下,您必须configure CORS on the Web API to allow cross-origin calls。这在文档here 中有解释
-
处理此问题的正确方法是添加源,而不是禁用端口。这样做很容易,在您的 CORS 配置中使用
policy.WithOrigins("http://localhost:5000", "https://localhost:5001")。至于In an former api project I developed in PHP,,黑客们也读过 SO,现在知道了他们可以针对特定目标尝试的另一个漏洞
标签: c# cors webapi blazor-webassembly