我在努力做什么

我有一个后台ASP。Net Core Web API托管在Azure免费计划上(源代码:https://github.com/killerrin/Portfolio-Backend)。

我也有一个客户端网站,我想让消费该API。客户端应用程序不会托管在Azure上,而是托管在Github Pages或我可以访问的其他Web托管服务上。正因为如此,域名不会排成一行。

研究这个问题,我需要在Web API端启用CORS,但是我已经尝试了几个小时,现在它拒绝工作。

我如何有客户端设置 它只是一个用React.js编写的简单客户端。我通过Jquery中的AJAX调用api。React网站工作,所以我知道它不是。Jquery API调用工作,我在尝试1确认。我是这样打电话的

    var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
    //alert(username + "|" + password + "|" + apiUrl);
    $.ajax({
        url: apiUrl,
        type: "POST",
        data: {
            username: username,
            password: password
        },
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            var authenticatedUser = JSON.parse(response);
            //alert("Data Loaded: " + authenticatedUser);
            if (onComplete != null) {
                onComplete(authenticatedUser);
            }
        },
        error: function (xhr, status, error) {
            //alert(xhr.responseText);
            if (onComplete != null) {
                onComplete(xhr.responseText);
            }
        }
    });

我所尝试过的


尝试1 -“正确”的方式

https://learn.microsoft.com/en-us/aspnet/core/security/cors

我已经遵循微软网站上的本教程,尝试在Startup.cs中全局启用它的所有3个选项,在每个控制器上设置它,并在每个动作上尝试它。

按照这种方法,跨域工作,但只能在单个控制器上的单个动作上工作(POST到AccountController)。对于其他任何事情,Microsoft.AspNetCore.Cors中间件拒绝设置头文件。

我通过NUGET安装了Microsoft.AspNetCore.Cors,版本为1.1.2

下面是我如何在Startup.cs中设置它

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add Cors
        services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        }));

        // Add framework services.
        services.AddMvc();
        services.Configure<MvcOptions>(options =>
        {
            options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
        });

        ...
        ...
        ...
    }

    // This method gets called by the runtime. Use this method to configure 
    //the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
    ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        // Enable Cors
        app.UseCors("MyPolicy");

        //app.UseMvcWithDefaultRoute();
        app.UseMvc();

        ...
        ...
        ...
    }

如你所见,我都是照做的。我两次都在MVC之前添加了Cors,当这不起作用时,我尝试在每个控制器上都添加[EnableCors(“MyPolicy”)]

[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller

尝试2 -暴力强迫它

https://andrewlock.net/adding-default-security-headers-in-asp-net-core/

在尝试了几个小时的前一次尝试后,我认为我应该尝试手动设置头,强制它们在每个响应上运行。我在本教程中介绍了如何手动为每个响应添加标题。

这些是我添加的头文件

.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")

这些是我尝试失败的其他头

.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")

有了这个方法,跨站点的头被正确地应用,他们显示在我的开发控制台和邮差。然而,问题是,当它通过访问控制-允许起源检查时,web浏览器抛出了一个嘘声(我相信)访问控制-允许头部声明415(不支持的媒体类型)

所以暴力法也不管用


最后

有没有人得到了这个工作,可以伸出手来,或者只是能够指出我在正确的方向?


EDIT

因此,为了让API调用顺利进行,我不得不停止使用JQuery,转而使用纯Javascript的XMLHttpRequest格式。

尝试1

我设法让Microsoft.AspNetCore.Cors通过遵循MindingData的答案工作,除了在配置方法中将app.UseCors放在app.UseMvc之前。

此外,当与Javascript API解决方案options.AllowAnyOrigin()混合时,通配符支持也开始工作。

尝试2

所以我已经设法让尝试2(暴力强迫它)工作…唯一的例外是,通配符访问控制-允许-起源不工作,因此我必须手动设置有权限访问它的域。

这显然不是理想的,因为我只是想让这个WebAPI对每个人都开放,但它至少在一个单独的网站上为我工作,这意味着它是一个开始

app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
    .AddDefaultSecurePolicy()
    .AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
    .AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
    .AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));

因为你有一个非常简单的CORS策略(允许来自XXX域的所有请求),所以你不需要把它弄得这么复杂。首先尝试执行以下操作(CORS的一个非常基本的实现)。

如果还没有安装,请安装CORS nuget包。

Install-Package Microsoft.AspNetCore.Cors

在startup.cs的ConfigureServices方法中,添加CORS服务。

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(); // Make sure you call this previous to AddMvc
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

然后在startup.cs的Configure方法中添加以下内容:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // Make sure you call this before calling app.UseMvc()
    app.UseCors(
        options => options.WithOrigins("http://example.com").AllowAnyMethod()
    );

    app.UseMvc();
}

现在试试吧。当你想对不同的操作(例如,不同的主机或不同的头)使用不同的策略时,可以使用策略。对于这个简单的例子,你真的不需要它。从这个简单的例子开始,然后根据需要进行调整。

进一步阅读:http://dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/


根据你在MindingData的回答中的评论,它与你的CORS无关,它工作得很好。

您的控制器操作返回错误的数据。HttpCode 415表示“不支持的媒体类型”。当你将错误的格式传递给控制器(即XML传递给只接受json的控制器)或当你返回错误的类型(在一个声明只返回XML的控制器中返回XML)时,就会发生这种情况。

为了以后检查操作上是否存在[Produces("…")]属性


尝试添加jQuery.support.cors = true;在Ajax调用之前

也可能是你发送给API的数据不可靠,

尝试添加以下JSON函数

        var JSON = JSON || {};

    // implement JSON.stringify serialization
    JSON.stringify = JSON.stringify || function (obj) {

        var t = typeof (obj);
        if (t != "object" || obj === null) {

            // simple data type
            if (t == "string") obj = '"' + obj + '"';
            return String(obj);

        }
        else {

            // recurse array or object
            var n, v, json = [], arr = (obj && obj.constructor == Array);

            for (n in obj) {
                v = obj[n]; t = typeof (v);

                if (t == "string") v = '"' + v + '"';
                else if (t == "object" && v !== null) v = JSON.stringify(v);

                json.push((arr ? "" : '"' + n + '":') + String(v));
            }

            return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
        }
    };

    // implement JSON.parse de-serialization
    JSON.parse = JSON.parse || function (str) {
        if (str === "") str = '""';
        eval("var p=" + str + ";");
        return p;
    };

然后在data: object中将其更改为

    data: JSON.stringify({
        username: username,
        password: password
    }),

在ConfigureServices中添加services.AddCors();之前services.AddMvc (); 在“配置”中添加UseCors app.UseCors(生成器=>生成器 .AllowAnyOrigin () .AllowAnyMethod () .AllowAnyHeader ()); app.UseMvc ();

重点是在app.UseMvc()之前添加app.UseCors。

确保在MVC之前声明CORS功能,以便中间件在MVC管道获得控制并终止请求之前触发。

在上面的方法起作用后,你可以改变它,配置一个特定的ORIGIN来接受api调用,避免让你的api对任何人开放

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
    {
        builder.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader();
    }));

    services.AddMvc();
}

在configure方法中告诉CORS使用刚刚创建的策略:

app.UseCors("ApiCorsPolicy");
app.UseMvc();

我刚找到了这篇关于这个主题的简明文章 https://dzone.com/articles/cors-in-net-core-net-core-security-part-vi


我创建了自己的中间件类,我认为。net核心中间件类有问题

public class CorsMiddleware
{
    private readonly RequestDelegate _next;

    public CorsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext httpContext)
    {
        httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
        httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
        return _next(httpContext);
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class CorsMiddlewareExtensions
{
    public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CorsMiddleware>();
    }
}

在startup。cs中就是这样使用的

app.UseCorsMiddleware();

在我的情况下,只有得到请求工作良好,根据MindingData的答案。对于其他类型的请求,你需要写:

app.UseCors(corsPolicyBuilder =>
   corsPolicyBuilder.WithOrigins("http://localhost:3000")
  .AllowAnyMethod()
  .AllowAnyHeader()
);

不要忘记添加。allowanyheader ()


为了扩展user8266077的回答,我发现我仍然需要在。net Core 2.1-preview中为preflight请求提供OPTIONS响应:

// https://stackoverflow.com/a/45844400
public class CorsMiddleware
{
  private readonly RequestDelegate _next;

  public CorsMiddleware(RequestDelegate next)
  {
    _next = next;
  }

  public async Task Invoke(HttpContext context)
  {
    context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
    context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    // Added "Accept-Encoding" to this list
    context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Accept-Encoding, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
    context.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
    // New Code Starts here
    if (context.Request.Method == "OPTIONS")
    {
      context.Response.StatusCode = (int)HttpStatusCode.OK;
      await context.Response.WriteAsync(string.Empty);
    }
    // New Code Ends here

    await _next(context);
  }
}

然后在Startup.cs中启用中间件

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseMiddleware(typeof(CorsMiddleware));
  // ... other middleware inclusion such as ErrorHandling, Caching, etc
  app.UseMvc();
}

以上的步骤都没有帮助,然后我读了一篇文章,解决了这个问题。

下面是代码。

public void ConfigureServices(IServiceCollection services)
{
    // Add service and create Policy with options
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials() );
    });


    services.AddMvc(); 
}

and

public void Configure(IApplicationBuilder app)
{
    // ...

    // global policy - assign here or on each controller
    app.UseCors("CorsPolicy");

在actionmethod的顶部

[EnableCors("CorsPolicy")]

我认为如果你使用自己的CORS中间件,你需要通过检查源头来确保它真的是CORS请求。

 public class CorsMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IMemoryCache _cache;
    private readonly ILogger<CorsMiddleware> _logger;

    public CorsMiddleware(RequestDelegate next, IMemoryCache cache, ILogger<CorsMiddleware> logger)
    {
        _next = next;
        _cache = cache;
        _logger = logger;
    }
    public async Task InvokeAsync(HttpContext context, IAdministrationApi adminApi)
    {
        if (context.Request.Headers.ContainsKey(CorsConstants.Origin) || context.Request.Headers.ContainsKey("origin"))
        {
            if (!context.Request.Headers.TryGetValue(CorsConstants.Origin, out var origin))
            {
                context.Request.Headers.TryGetValue("origin", out origin);
            }

            bool isAllowed;
            // Getting origin from DB to check with one from request and save it in cache 
            var result = _cache.GetOrCreateAsync(origin, async cacheEntry => await adminApi.DoesExistAsync(origin));
            isAllowed = result.Result.Result;

            if (isAllowed)
            {
                context.Response.Headers.Add(CorsConstants.AccessControlAllowOrigin, origin);
                context.Response.Headers.Add(
                    CorsConstants.AccessControlAllowHeaders,
                    $"{HeaderNames.Authorization}, {HeaderNames.ContentType}, {HeaderNames.AcceptLanguage}, {HeaderNames.Accept}");
                context.Response.Headers.Add(CorsConstants.AccessControlAllowMethods, "POST, GET, PUT, PATCH, DELETE, OPTIONS");

                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("CORS with origin {Origin} was handled successfully", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                await _next(context);
            }
            else
            {
                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("Preflight CORS request with origin {Origin} was declined", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                _logger.LogInformation("Simple CORS request with origin {Origin} was declined", origin);
                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                return;
            }
        }

        await _next(context);
    }

对我来说,这与我所使用的代码无关。对于Azure,我们必须进入应用程序服务的设置,在侧菜单中输入“CORS”。在那里,我必须添加我正在请求东西的域。一旦我有了它,一切都变得神奇了。


我得到了上面MindingData的答案,但我必须使用Microsoft.AspNet.Cors而不是Microsoft.AspNetCore.Cors。我在Visual Studio 2019中使用。net core Web Application API项目


最简单的方法是

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseCors(options => options.AllowAnyOrigin());

        app.UseHttpsRedirection();
        app.UseMvc();
    }

Startup.cs。


在launchSettings。在iisSettings下,将anonymousAuthentication设置为true:

"iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:4200/",
      "sslPort": 0
    }
  }

然后,在Startup.cs中,在ConfigureServices下,在services之前。AddMvc,添加:

services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
{
    builder
        .AllowAnyOrigin()
        .WithHeaders(HeaderNames.AccessControlAllowHeaders, "Content-Type")
        .AllowAnyMethod()
        .AllowCredentials();
}));

然后,在configure方法中,在app.UseMvc()之前添加:

app.UseCors("ApiCorsPolicy");

我为此纠结了好几天。

我终于让它通过移动app.UseCors(CORS_POLICY);到Configure()的顶部。

https://weblog.west-wind.com/posts/2016/sep/26/aspnet-core-and-cors-gotchas 确保在> MVC之前声明CORS功能 头必须在MVC完成请求之前应用。 <=即使我的应用程序没有调用UseMVC(),移动UseCors()到顶部修复了这个问题

另外:

Microsoft.AspNetCore.Cors used to be a required NuGet package in .Net Core 2 and lower; it's now automatically a part of Microsoft.AspNetCore in .Net Core 3 and higher. builder.AllowAnyOrigin() and .AllowCredentials() CORS options are now mutually exclusive in .Net Core 3 and higher CORS policy seems to require Angular call the server with https. An http URL seemed to give a CORS error regardless of the .Net Core server's CORS configuration. For example, http://localhost:52774/api/Contacts would give a CORS error; simply changing the URL to https://localhost:44333/api/Contacts worked.

另外注意:

在我的情况下,CORS不会工作,直到我移动app.UseCors()以上app.UseEndpoints(endpoints => endpoints. mapcontrollers())。


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {      
       app.UseCors(builder => builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .SetIsOriginAllowed((host) => true)
                .AllowCredentials()
            );
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
    }

.NET Core 3.1

对我来说很有效,医生也这么说:

在创业班:

readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; 

在ConfigureServices()方法中:

    services.AddCors(options =>
    {
        options.AddPolicy(MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("http://example.com",
                                "http://www.contoso.com");
        });
    });

在Configure()方法中:

    app.UseCors(MyAllowSpecificOrigins);  

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


The

Microsoft.AspNetCore.Cors

将允许您使用内置功能进行CORS,但它不处理OPTIONS请求。 到目前为止,最好的解决方法是创建一个新的中间件,就像之前的文章中建议的那样。检查以下帖子中标记为正确的答案:

启用。net核心Web API中CORS的OPTIONS头


简单易行的方法。

安装包

安装包Microsoft.AspNetCore.Cors

把下面的代码放在startup.cs文件中

app.UseCors(options => options. allowanyorigin ());


我使用的是。net CORE 3.1,当我意识到我的代码已经开始实际工作,但我的调试环境被打破时,我花了很长时间用这一个敲我的头,所以如果你试图排除问题,这里有2个提示:

如果您试图使用ASP记录响应头。NET中间件,“Access-Control-Allow-Origin”头即使在那里也不会显示。我不知道如何,但它似乎是在管道之外添加的(最后我不得不使用wireshark来查看它)。 . net CORE不会在响应中发送“Access-Control-Allow-Origin”,除非你的请求中有一个“Origin”头。邮差不会自动设置,所以你需要自己添加。


这是我的代码:)

  app.Use((ctx, next) =>
        {
            ctx.Response.Headers.Add("Access-Control-Allow-Origin", ctx.Request.Headers["Origin"]);
            ctx.Response.Headers.Add("Access-Control-Allow-Methods", "*");
            ctx.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            ctx.Response.Headers.Add("Access-Control-Allow-Headers", "AccessToken,Content-Type");
            ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*");
            if (ctx.Request.Method.ToLower() == "options")
            {
                ctx.Response.StatusCode = 204;

                return Task.CompletedTask;
            }
            return next();
        });

在我的情况下,我在UserRouting之前修复了UseCors ..


我是这样做的。

我看到在一些答案中,他们正在设置app.UserCors(“xxxPloicy”),并在控制器中放置[EnableCors(“xxxPloicy”)]。你不需要同时做两件事。

以下是步骤。

在ConfigureServices的Startup.cs中添加以下代码。

    services.AddCors(c=>c.AddPolicy("xxxPolicy",builder => {
        builder.AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader();
    }));

如果你想在整个项目中应用,那么在Startup.cs中的Configure方法中添加以下代码

app.UseCors("xxxPolicy");

Or

如果你想把它添加到特定的控制器,然后添加enable cors代码,如下所示。

[EnableCors("xxxPolicy")]
[Route("api/[controller]")]
[ApiController]
public class TutorialController : ControllerBase {}

更多信息,请看这个


使用自定义动作/控制器属性来设置CORS头。

例子:

public class AllowMyRequestsAttribute : ControllerAttribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        // check origin
        var origin = context.HttpContext.Request.Headers["origin"].FirstOrDefault();
        if (origin == someValidOrigin)
        {
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", origin);
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*");
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", "*");
            // Add whatever CORS Headers you need.
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        // empty
    }
}

然后在Web API控制器/动作中:

[ApiController]
[AllowMyRequests]
public class MyController : ApiController
{
    [HttpGet]
    public ActionResult<string> Get()
    {
        return "Hello World";
    }
}

只是补充回答这里,如果你正在使用app. usehttpredirection(),你正在击中非SSL端口考虑注释掉这个。


我使用blazor webassembly作为客户端和asp.net web api核心作为后端,也有cors问题。

我用这些代码找到了解决方案:

我的ASP。Net core web api Startup.cs ConfigureServices和Configure方法的第一行是这样的:

public void ConfigureServices(IServiceCollection services)
{
   services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
   {
        builder.WithOrigins("http://example.com").AllowAnyMethod().AllowAnyHeader();
    }));

 //other code below...
}

和我的Configure方法:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseCors(
        options =>   options.WithOrigins("http://example.com").AllowAnyMethod().AllowAnyHeader()
            );
 //other code below...
}

用客户端域或IP地址更改http://example.com


在我的情况下,字符/在我的原始名称的末尾引起了一个问题。

在.NET Core 3.1中为我解决的解决方案:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(c => c.AddPolicy("PolicyName", policy => {
        policy.WithOrigins("http://localhost:3000")
        .AllowAnyMethod()
        .AllowAnyHeader();
    }));
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseCors("PolicyName");
}

下面是对我有效的设置:


在ASP中对我有效的解决方案。NET Core 3.1:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader());
            });
            services.AddControllersWithViews();
        }

然后修改如下:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseCors("CorsPolicy");

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }

程序运行正常,错误得到解决。


对于。net CORE 3.1

在我的例子中,我在添加cors中间件之前使用了https重定向,并且能够通过改变它们的顺序来修复这个问题

我的意思是:

改变:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {

      ...
        
        app.UseHttpsRedirection();  

        app.UseCors(x => x
            .AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader());

      ...

     }

:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {

      ...
        
        app.UseCors(x => x
            .AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader());

        app.UseHttpsRedirection(); 

      ...

     }

顺便说一下,允许来自任何来源和方法的请求在生产阶段可能不是一个好主意,您应该在生产阶段编写自己的cors策略。


ASP。NET Core 3.1解决了我的问题 https://jasonwatmore.com/post/2020/05/20/aspnet-core-api-allow-cors-requests-from-any-origin-and-with-credentials

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();
            services.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.UseRouting();

            // global cors policy
            app.UseCors(x => x
                .AllowAnyMethod()
                .AllowAnyHeader()
                .SetIsOriginAllowed(origin => true) // allow any origin
                .AllowCredentials()); // allow credentials

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(x => x.MapControllers());
        }
    }

对我来说,它开始工作时,我已经明确设置的头,我正在发送。我添加了content-type header,然后它就工作了。

.net

.WithHeaders("Authorization","Content-Type")

javascript:

this.fetchoptions = {
        method: 'GET', 
        cache: 'no-cache', 
        credentials: 'include', 
        headers: {
            'Content-Type': 'application/json',
        },
        redirect: 'follow', 
    }; 

AspNetCoreModuleV2不能处理导致飞行前问题的OPTIONS

我发现。net core模块不能很好地处理OPTIONS,这造成了一个大的CORS问题:

解决方法:去掉星号*

在网络上。配置,从模块中排除OPTIONS谓词,因为此谓词已经被IIS OPTIONSVerbHandler处理:

 <add name="aspNetCore" path="*" verb="* modules="AspNetCoreModuleV2" resourceType="Unspecified" />

用这个

<add name="aspNetCore" path="*" verb="GET,POST,PUT,DELETE" modules="AspNetCoreModuleV2" resourceType="Unspecified" />

对我来说,解决办法是纠正顺序:

app.UseCors();
app.UseAuthentication();
app.UseAuthorization();

下面是。net 6中使用顶级语句配置CORS的Program.cs文件示例。可以看到,builder.Services.AddCors和app.UseCors是必需的语句。两个带注释的UseCors语句也可以工作,并用于显示其他选项。我没有对ASP做任何更改。NET API控制器。

作为参考,我的Angular开发应用程序运行在localhost:4200上,并连接到开发ASP。NET API服务器使用https://localhost:7262。

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors();
var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

//app.UseCors(options => options.WithOrigins("http://localhost:4200").AllowAnyMethod());
//app.UseCors(options => options.WithOrigins("http://localhost:4200").WithMethods(new string[] {"POST", "PUT"}));
app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod());

app.MapControllers();

app.Run();

对于。net Core 6

var builder = WebApplication.CreateBuilder(args);
var apiCorsPolicy = "ApiCorsPolicy";

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: apiCorsPolicy,
                      builder =>
                      {
                          builder.WithOrigins("http://localhost:4200", "https://localhost:4200")
                            .AllowAnyHeader()
                            .AllowAnyMethod()
                            .AllowCredentials();
                            //.WithMethods("OPTIONS", "GET");
                      });
});

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();

var app = builder.Build();
app.UseHttpsRedirection();

app.UseCors(apiCorsPolicy);

app.UseAuthorization();
app.MapControllers();
app.Run();

这里有更多的例子


请去项目属性 选中“启用匿名认证” 这对我来说很好。 该图像显示了


如果CORS策略发生了,你可以看到inspect element => network…来处理这个问题,你可以把你的客户端应用URL或ip/port引入到。net core app中

var  MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
                      policy  =>
                      {
                          policy.WithOrigins("http://example.com",
                                              "http://www.contoso.com");
                      });
});

// services.AddResponseCaching();

builder.Services.AddControllers();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(MyAllowSpecificOrigins);

app.UseAuthorization();

app.MapControllers();

app.Run();

详情请浏览:https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-7.0