405(不允许的方法)并被 CORS 策略阻止

Yan*_*iav 3 c# asp.net-core asp.net-core-webapi angular

我在客户端有基于 Angular(7.2.1) 的 UI 的 Asp.Net Core(3) WebApi 项目。使用 Postman 或仅使用 URL 时,我可以使用 GET 和 POST 而不会出现任何特定错误。通过 Angular(Chrome\FireFox\IE Browser) 尝试相同的操作时,我收到以下错误。

zone.js:3243 OPTIONS http://localhost:8888/api/PaymentDetails 405 (Method Not Allowed) ccess to XMLHttpRequest at 'http://localhost:8888/api/PaymentDetails' from origin 'http://localhost:4200' 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.

我会尽量分享尽可能多的代码来演示流程。

WebApi Startup.cs:

公共 IConfiguration 配置 { 获取;}

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{

    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder =>
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader()

                );
    });
    services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
            options.JsonSerializerOptions.PropertyNamingPolicy = null;
        });

    services.AddDbContext<PaymentDetailContext>(options => options.UseSqlServer("Server=DESKTOP-KT0N2RN\\SQLEXPRESS;DataBase=PaymentDetailDB;Trusted_Connection=True;MultipleActiveResultSets=True;"));

}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{


    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    app.UseCors("CorsPolicy");
}
Run Code Online (Sandbox Code Playgroud)

WebAPI GET 方法:

[HttpGet]
public async Task<ActionResult<IEnumerable<PaymentDetail>>> GetPaymentDetails()
{
    return await _context.PaymentDetails.ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)

客户端:

rootUrl: string = "http://localhost:8888/api";

getPaymentDetail()
{

    console.log(`${this.rootUrl}/PaymentDetails`)
    const headers = new HttpHeaders().set('Content-Type','application/json');
    // headers.append('Access-Control-Allow-Origin', '*');
    // headers.append('Access-Control-Allow-Headers','Origin, X-Requested-With, Content-Type, Accept');
    return this._http.get(`${this.rootUrl}/PaymentDetails`,{headers:headers});
}
Run Code Online (Sandbox Code Playgroud)

Kev*_*vin 7

我认为改变以下Startup Configure应该工作。注意顺序:根据文档

对于端点路由,必须将 CORS 中间件配置为在对 UseRouting 和 UseEndpoints 的调用之间执行。不正确的配置将导致中间件停止正常运行。

app.UseRouting();

app.UseAuthorization();

app.UseCors("CorsPolicy");

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});
Run Code Online (Sandbox Code Playgroud)

我认为 COR 的快速摘要可能有助于解释邮递员请求为何对您有用。

默认情况下,在浏览器中使用 CORS 来检查哪些源服务器将接受来自的请求。

如果您对服务器的请求来自同一来源(来源的所有部分都必须匹配),则您的 CORS 请求不会失败,因为它不是跨来源的。在您的情况下,端口不匹配,因此即使服务器和 Web 应用程序都从您的本地主机运行,它也算作跨源,因为端口不匹配

当您发送请求时,浏览器将首先发送一个选项请求(预检请求),该请求将显示受支持的方法并检查您的源(您的前端 Web 应用程序)是否有权向服务器发送请求。默认情况下,此功能内置于大多数主要浏览器(Chrome、Firefox、Edge 等)中。

您的邮递员请求有效,因为邮递员不发送预检请求。

进一步阅读:

启用 CORS

https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1

什么是 CORS

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

  • 问题是我在 `app.UseMvc` 之后使用了 `app.UseCors()` (2认同)