CORS 不适用于从 Ajax 到 ASP.NET Core Web API 的调用

Posted

技术标签:

【中文标题】CORS 不适用于从 Ajax 到 ASP.NET Core Web API 的调用【英文标题】:CORS not working for calls from Ajax to ASP.NET Core Web API 【发布时间】:2021-02-08 00:04:48 【问题描述】:

它会在 Ajax 调用中引发此错误。 我还在 Startup.cs 中使用命名策略尝试了这些行。我在网上找到的所有方法都不起作用。 我确定我在某个地方犯了一些愚蠢的错误,我没有看到它。

builder.WithOrigins("https://localhost:44380")
builder.WithOrigins("localhost:44380")
builder.WithOrigins("localhost")
[EnableCors("MyPolicy")] //in Controller.cs

来自 Chrome 浏览器控制台的错误:

Controller.cs

[Route("api/itexit")]
[EnableCors]
[ApiController]
public class ITExitController : ControllerBase

    //code...

Startup.cs

public void ConfigureServices(IServiceCollection services)

    services.AddControllers();
    services.AddSwaggerGen();

    services.AddCors();

    string connectionString = Configuration.GetConnectionString("DefaultConnection");
    services.AddDbContext<CoCFormsContext>(options => options.UseSqlServer(connectionString));

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    if (env.IsDevelopment())
    
        app.UseDeveloperExceptionPage();
    

    app.UseSwagger();
    app.UseSwaggerUI(c =>
    
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "CoCForms.API");
    );

    app.UseHttpsRedirection();

    app.UseRouting();
    app.UseCors(builder =>
    
        builder
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader();
    );
    app.UseAuthorization();

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

来自 .cshtml 页面的 Ajax 调用

$.ajax(
    url: url,
    type: "GET",
    crossDomain: true,
    dataType: 'json',
    //dataType: 'jsonp',
    success: function (data,textstatus,jqXHR) 
//process data
    ,
    error: function (jqXHR, textstatus, exception) 
//process exception
    
);

【问题讨论】:

【参考方案1】:

尝试像这样使用命名策略:

 services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
            
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            ));

还有这个

 app.UseCors("MyPolicy");

在这种情况下,您不需要控制器中的 [EnableCors]。仅当您使用 AddDefaultPolicy....时才需要它。

【讨论】:

人们通常使用 contentType: 'json',而不是 dataType,可能它不相关,但我没有看到任何操作(和任何操作路线) 你是否交换了 AddCors 和 UseCors? 我的错,问题是 api 需要 Windows 身份验证。我不得不更改 Startup.cs 中的代码。我将代码发布为答案【参考方案2】:

真正的问题是 API 需要 Windows 身份验证。错误确实是

401.2 未经授权

,它没有显示在 Chrome 控制台中。我通过从另一个 C# 项目而不是 Ajax 调用调用 api 发现了“未授权”错误。

进行以下更改后,它现在可以工作了。

在 Ajax 调用中添加了这些附加行:

crossDomain: true,
xhrFields: 
    withCredentials: true
,

更新的 Ajax 调用:

$.ajax(
    url: url,
    type: "GET",
    crossDomain: true,
    dataType: 'json',
    xhrFields: 
        withCredentials: true
    ,
    success: function (data,textstatus,jqXHR) 
        //process data
    ,
    error: function (jqXHR, textstatus, exception) 
        //process exception
    
);

在 Startup.cs 中添加了这一行 将AllowAnyOrigin()替换为

builder.SetIsOriginAllowed(_ => true)

并添加了这一行

services.AddAuthentication(IISDefaults.AuthenticationScheme);

更新了 Startup.cs

public void ConfigureServices(IServiceCollection services)

    services.AddControllers();
    services.AddAuthentication(IISDefaults.AuthenticationScheme);
    services.AddSwaggerGen();

    services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
    
        builder.SetIsOriginAllowed(_ => true)
               .AllowAnyMethod()
               .AllowAnyHeader()
               .AllowCredentials();
    ));

    string connectionString = Configuration.GetConnectionString("DefaultConnection");
    services.AddDbContext<CoCFormsContext>(options => options.UseSqlServer(connectionString));


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    if (env.IsDevelopment())
    
        app.UseDeveloperExceptionPage();
    

    app.UseSwagger();
    app.UseSwaggerUI(c =>
    
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "CoCForms.API");
    );

    app.UseHttpsRedirection();

    app.UseRouting();
    app.UseCors("MyPolicy");
    app.UseAuthorization();

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

为控制器添加了[Authorize] 属性

[Route("api/itexit")]
[ApiController]
[Authorize]

【讨论】:

以上是关于CORS 不适用于从 Ajax 到 ASP.NET Core Web API 的调用的主要内容,如果未能解决你的问题,请参考以下文章

CORS 不适用于 ASP NET 5 Web Api

ValidateAntiforgeryToken 不适用于 ASP.NET MVC 中的 Ajax

ASP.NET C# SuppressFormsAuthenticationRedirect 不适用于 Ajax POST?

添加 FriendlyUrls 时,jQuery ajax 调用不适用于 ASP.Net Web 窗体

Cors Ajax 请求适用于子域但不适用于主域

Asp.Net MVC 5 Jquery 验证不适用于带有提交事件的 ajax 帖子,显示为有效表单