CORS 不适用于 .NET Core API 和 Angular 前端

Posted

技术标签:

【中文标题】CORS 不适用于 .NET Core API 和 Angular 前端【英文标题】:CORS is not working with .NET Core API and Angular frontend 【发布时间】:2021-03-12 21:35:13 【问题描述】:

我已经阅读了类似的问题,尝试了其中提到的几个解决方案,但没有任何成功 - 问题很简单,我真的不知道到底哪里错了......

我有一个非常简单的 .NET Core API,我想在其上设置 CORS。

我试过这种方式(端点路由):https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-5.0#enable-cors-with-endpoint-routing

Startup.cs 中的ConfigureServices() 和Configure() 方法

就是默认生成的,只是添加了MSDN上的CORS相关代码。

      public void ConfigureServices(IServiceCollection services)
      
           services.AddCors(options =>
           
               options.AddPolicy(name: "Policy1",
                    builder =>
                    
                        // I read the site url from appsettings.json but for now I want to keep the example as simple as I can
                        // var lpSolverFrontendUrl = Configuration.GetValue<string>("Cors:AllowedSite");
                        builder.WithOrigins("http://localhost:4200").AllowAnyHeader().AllowAnyMethod();
                    );
            );
            services.AddControllers();
        

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        
            if (env.IsDevelopment())
            
                app.UseDeveloperExceptionPage();
            

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseCors();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            
                endpoints.MapControllers().RequireCors("Policy1");
            );
        

我的控制器类

    [Route("[controller]/[action]")]
    public class SimplexSolverController : Controller
    
        public IActionResult Ping()
        
            return Json(new  status = "OK" );
        

        [HttpPost]
        public IActionResult Solve([FromBody] LPModelDto lpModelDto)
        
            bool wrongFormat = false;
            string message = null;
            SimplexSolutionDto solution = null;
            //...
        
        //...
   

我已经尝试过的另一种方式(带有属性):https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-5.0#enable-cors-with-attributes

Startup.cs 以这种方式

        public void ConfigureServices(IServiceCollection services)
        
           services.AddCors(options =>
           
               options.AddPolicy(name: "Policy1",
                    builder =>
                    
                        // I read the site url from appsettings.json but I want to keep the example as simple as I can
                        // var lpSolverFrontendUrl = Configuration.GetValue<string>("Cors:AllowedSite");
                        builder.WithOrigins("http://localhost:4200").AllowAnyHeader().AllowAnyMethod();
                    );
            );
            services.AddControllers();
        

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        
            if (env.IsDevelopment())
            
                app.UseDeveloperExceptionPage();
            

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseCors();

            app.UseAuthorization();

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

这样我的控制器类

我将 EnableCors 属性放在控制器方法上以启用 CORS。

    [Route("[controller]/[action]")]
    public class SimplexSolverController : Controller
    
        public IActionResult Ping()
        
            return Json(new  status = "OK" );
        

        [EnableCors("Policy1")]
        [HttpPost]
        public IActionResult Solve([FromBody] LPModelDto lpModelDto)
        
            bool wrongFormat = false;
            string message = null;
            SimplexSolutionDto solution = null;
             //...
        
        //...
   

无论我选择哪种方式,我都会在 DevTools 控制台中收到错误,例如:Access to XMLHttpRequest at 'http://localhost:4000/simplexsolver/solve' from origin 'http://localhost:4200'已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。

我完全按照文章所说的但没有任何结果...感谢任何帮助!

更新

我终于成功启用了CORS。可悲的是,我无法在 ConfigureServices 中设置任何类型的策略,因为如果我这样做,Access-Control-Allow-Origin 标头将在预检中具有“*”值(不是前端的地址)请求的响应。我使用的方式是:

在 ConfigureServices() 方法中只添加 CORS 而不添加任何策略 在 Configure() 中,我将余量确定为 UseCors() 方法的参数 (无需以这种方式将 EnableCors 属性放在控制器方法上。)

现在我在 Startup.cs 中的两个方法如下所示:

        public void ConfigureServices(IServiceCollection services)
        
            services.AddCors();
            services.AddControllers();
        

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        
            if (env.IsDevelopment())
            
                app.UseDeveloperExceptionPage();
            

            app.UseCors(options => options.WithOrigins(Configuration.GetValue<string>("Cors:AllowedSite")).AllowAnyMethod().AllowAnyHeader().AllowCredentials());

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

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

感谢您为我提供的所有答案!我希望这对将来的某人有所帮助。但我仍然很奇怪将 CORS 与策略一起使用有什么问题。

【问题讨论】:

有趣。但是调试器出现了什么?是否发生了飞行前请求(developer.mozilla.org/en-US/docs/Glossary/Preflight_request)? 请考虑看这里github.com/dotnet/aspnetcore/issues/20709。出于调试目的,您可能喜欢使用:app.UseCors(options =&gt; options.SetIsOriginAllowed(x =&gt; _ = true).AllowAnyMethod().AllowAnyHeader().AllowCredentials()); // This is needed to set everything as allowed. 是否可以正常工作。 您好,预检请求是由浏览器发送的。问题是 Access-Control.Allow-Origin 的值为“*”,而不是 Angular 站点的 url。 似乎可以通过在 UseCors() cass 中定义余量作为参数来解决 :) 请参阅更新 【参考方案1】:

将您的代码修复为:


 app.UseCors("Policy1");

services.AddCors(options =>
           
               options.AddPolicy("Policy1",
                    builder =>
                    
                       
                       .builder.WithOrigins("http://localhost:4200")
                       .AllowAnyHeader()
                       .AllowAnyMethod();
                    );
            );

然后删除

[EnableCors("Policy1")]

来自控制器操作。

【讨论】:

【参考方案2】:

我能够在 .NET Core 3.1 中像这样在全球范围内允许 CORS:

Startup.cs 代码:

public void ConfigureServices(IServiceCollection services)
    
        services.AddControllers();
        services.AddCors(options => 
        
            options.AddPolicy(name: "AllowCORS", builder =>
            
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            );
        );
    

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    
        if (env.IsDevelopment())
        
            app.UseDeveloperExceptionPage();
        

        app.UseCors("AllowCORS");

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

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

【讨论】:

【参考方案3】:

使用这个:

public void ConfigureServices(IServiceCollection services)
        
            services.AddCors(options =>
            
                options.AddPolicy("AllowOrigin", builder => 
                        builder.AllowAnyOrigin()
                               .AllowAnyHeader()
                               .AllowAnyMethod());
            );
         
            //...
        

如果不行,设置 Mvc 兼容版本为 3.0 使用

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

像这样:

public void ConfigureServices(IServiceCollection services)
        
            services.AddCors(options =>
            
                options.AddPolicy("AllowOrigin", builder => 
                        builder.AllowAnyOrigin()
                               .AllowAnyHeader()
                               .AllowAnyMethod());
            );
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
            
            //...
        

【讨论】:

以上是关于CORS 不适用于 .NET Core API 和 Angular 前端的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core CORS 配置不适用于 Firefox

.net core 3.1 c# cors 不适用于 Angular 7

Set-cookie 不适用于 Dot net Core 3.1 中的跨站点请求/响应和 React 设置同站点 cookie 和/或 CORS 问题

.NET Web API CORS 不适用于所有路由

CORS 不适用于 ASP NET 5 Web Api

对外部 API 的 HTTP 请求适用于 .NET,但不适用于 React(CORS 问题)