简体   繁体   English

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

[英]CORS is not working with .NET Core API and Angular frontend

I have already read through the similar questions, tried a couple of the solutions mentioned in them but without any success - the problem is quite simple, I really don't know what the hell could be set wrong...我已经阅读了类似的问题,尝试了其中提到的几个解决方案但没有成功 - 问题很简单,我真的不知道到底是什么地方错了......

I have a very simple .NET Core API on which I want to set CORS.我有一个非常简单的 .NET 核心 API,我想在其上设置 CORS。

I have tried this way (endpoint routing): https://learn.microsoft.com/en-us/as.net/core/security/cors?view=as.netcore-5.0#enable-cors-with-endpoint-routing我试过这种方式(端点路由): https://learn.microsoft.com/en-us/as.net/core/security/cors?view=as.netcore-5.0#enable-cors-with-endpoint-路由

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

It's exactly the default one which is generated by default, only added the CORS-related code from MSDN.完全是默认生成的,只是添加了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");
            });
        }

My controller class我的 controller class

    [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;
            //...
        }
        //...
   }

The other way I have already tried (with attributes): https://learn.microsoft.com/en-us/as.net/core/security/cors?view=as.netcore-5.0#enable-cors-with-attributes我已经尝试过的另一种方式(带属性): https://learn.microsoft.com/en-us/as.net/core/security/cors?view=as.netcore-5.0#enable-cors-with-属性

Startup.cs this way 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();
            });
        }

My controller class this way我的controller class这样

I put the EnableCors attribute on the controller method to enable CORS on it.我将EnableCors属性放在 controller 方法上以在其上启用 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;
             //...
        }
        //...
   }

No matter which way I choose I get an error in DevTools console, like: Access to XMLHttpRequest at 'http://localhost:4000/simplexsolver/solve' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.无论我选择哪种方式,我都会在 DevTools 控制台中收到错误消息,例如:从来源“http://localhost:4200”访问“http://localhost:4000/simplexsolver/solve”中的 XMLHttpRequest 已被 CORS 策略阻止: 请求的资源上不存在“Access-Control-Allow-Origin”header。

I exactly followed what the article said but without any result... I appreciate any help!我完全按照文章所说的进行操作,但没有任何结果......感谢您的帮助!

UPDATE更新

I succeeded to enable CORS finally.我终于成功启用了CORS。 The sad thing is that I am not be able to set any kind of policy in ConfigureServices, because if I do so, the Access-Control-Allow-Origin header will have a "*" value (not the frontend's address) in the preflight request's response.可悲的是,我无法在 ConfigureServices 中设置任何类型的策略,因为如果我这样做,Access-Control-Allow-Origin header 将在预检中具有“*”值(不是前端地址)请求的响应。 The way I used is:我使用的方式是:

  • In the ConfigureServices() method only adding CORS without adding any policy在 ConfigureServices() 方法中只添加 CORS 不添加任何策略
  • In Configure() I determine the allowance as parameter of the UseCors() method (No need for EnableCors attribute to be put on controller .nethod this way.)在 Configure() 中,我将允许量确定为 UseCors() 方法的参数(无需将 EnableCors 属性放在 controller .nethod 上。)

Now my two methods in Startup.cs looks like this:现在我在 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();
            });
        }

Thank you for all of the answers I got.谢谢你给我的所有答案。 I hope this will help someone in the future.我希望这会在将来帮助某人。 But it is still strange to me what was wrong with using CORS with a policy.但是我仍然很奇怪将 CORS 与策略一起使用有什么问题。

Fix your code to this:将您的代码修复为:


 app.UseCors("Policy1");

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

And remove并删除

[EnableCors("Policy1")]

from controller actions.从 controller 动作。

I was able to allow CORS globally like this in .NET Core 3.1:我能够在 .NET Core 3.1 中像这样全局地允许 CORS :

Startup.cs code: 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();
        });
    }

Use this:用这个:

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

If it does not work, set Mvc compatibility version to 3.0 using如果它不起作用,请将 Mvc 兼容版本设置为 3.0 使用

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

like this:像这样:

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

I needed to change order of the call the app.UseCors("CORS_POLICY") in configure.我需要在配置中更改调用 app.UseCors("CORS_POLICY") 的顺序。

Not works:无效:

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
                   
        app.ConfigureMetrics();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseUserContextClaimsInjector();
        app.UseGlobalExceptionHandlerMiddleware();
        app.UseResponseCompression();
        app.UseSwagger();
        app.UseSwaggerUI();
        app.UseStaticFiles();
        app.ConfigureHealthCheck();           
        app.UseResponseCompression();

        app.UseCors("CORS_POLICY");

Works:作品:

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        
        app.UseCors("CORS_POLICY");
        
        app.ConfigureMetrics();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseUserContextClaimsInjector();
        app.UseGlobalExceptionHandlerMiddleware();
        app.UseResponseCompression();
        app.UseSwagger();
        app.UseSwaggerUI();
        app.UseStaticFiles();
        app.ConfigureHealthCheck();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM