【问题标题】:Cross-Origin Request Blocked: (Reason: CORS request did not succeed)Cross-Origin Request Blocked:(原因:CORS 请求未成功)
【发布时间】:2021-08-08 02:39:46
【问题描述】:

我正在开发一个全栈应用程序,后端使用 ASP.NET core 5.0 Web Api,前端使用 Angular 12。

向后端发送 http post 请求时,我收到与 CORS 策略相关的错误。

错误是:

跨域请求被阻止:同源策略不允许读取位于 http://localhost:5001/api/v1/user/login 的远程资源。 (原因:CORS 请求未成功)。

我查看了这个链接: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSDidNotSucceed,但它没有给我足够的信息来提出解决方案

我相信我的问题可能与第一个要点有关:

尝试访问具有无效证书的 https 资源会导致此错误

因为我的前端使用http协议,而我的后端使用https协议。

什么是有效证书?

我的网络浏览器中也没有安装广告拦截器,所以我想不出其他可以尝试的方法,因为我相信我在以下代码中启用了 CORS。

关于出了什么问题有什么想法吗?我可能缺少某种配置或其他东西?


代码示例

后端

startup.cs

// startup.cs
using MyApi.Installers;

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace MyApi
{
    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)
        {
            // CORS CONFIGURED HERE           
            services.AddCors(options =>
            {
                options.AddPolicy("CorsApi",
                    builder => builder.WithOrigins("http://localhost:4200")
                .AllowAnyHeader()
                .AllowAnyMethod());
            });

            // This is an extension method that installs swagger, jwt, services, etc...
            // I can add those also if need be
            services.InstallServicesInAssembly(Configuration);
        }

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

            SwaggerOptions swaggerOptions = new SwaggerOptions();
            Configuration.GetSection(nameof(SwaggerOptions)).Bind(swaggerOptions);

            app.UseSwagger(options => options.RouteTemplate = swaggerOptions.JsonRoute);
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint(swaggerOptions.UiEndpoint, swaggerOptions.Description);
                options.RoutePrefix = System.String.Empty;
            });

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            // CORS ENABLED HERE
            app.UseCors("CorsApi");

            app.UseAuthorization();

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

UserController.cs -> 登录函数

// UserController.cs -> Login function
        [HttpPost(ApiRoutes.User.Login)]
        public IActionResult Login([FromBody] UserLoginRequest request)
        {
            if (!ModelState.IsValid)
            {

                return BadRequest();
            }

            // Validates users credentials
            if (!_userService.IsValidUserCredentials(request.Email, request.Password))
            {
                return Unauthorized();
            }

            return Ok(});
        }

前端

auth-service.ts

// auth.service.ts
export class AuthService {

  private readonly baseUrl = 'https://localhost:5001/api/v1';

  // Adds CORS header to the request?
  private httpOptions = { headers: new HttpHeaders({ 'Content-Type':'application/json','Access-Control-Allow-Origins':'*'})};

  constructor(
    private http: HttpClient
  ) { }

  login(email: string, password: string): Observable<any> {
    let postData = new FormData();
    postData.append('email', email);
    postData.append('password', password);

    return this.http.post<any>(`${this.baseUrl}/user/login`, postData, this.httpOptions);
  }
}

login.component.ts

// login.component.ts
export class LoginComponent implements OnInit {
  loginForm = this.fb.group({
    email: ['', Validators.compose([Validators.email, Validators.required])],
    password: ['', Validators.required]
  });

  constructor(
    private authService: AuthService,
    private router: Router,
    private fb: FormBuilder,
  ) { }

  ngOnInit(): void { }

  get f() {
    return this.loginForm.controls;
  }

  login(form: FormGroup): void {
    // These output in console window
    console.log(this.f.email.value);
    console.log(this.f.password.value);

    // Error here
    this.authService.login(this.f.email.value, this.f.password.value).subscribe(
      response => {
        // This does not get output
        console.log(response);
        //this.router.navigate(['/home']);
      },
      error => console.log(error)
    );
  }

}

我试图让代码尽可能简单。

编辑:忘了提到我也启用了这个:

【问题讨论】:

  • 在您的 configureservices 中尝试此 services.AddCors(options => { options.AddPolicy("AllowAllHeaders", builder => { builder.AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod(); }); });并在您的配置中尝试此 app.UseCors("AllowAllHeaders");应该是第一行,在你的控制器中试试这个 [EnableCors("AllowAllHeaders")]
  • @Nonik 我尝试了你所说的并收到 500 错误,它告诉我 app.UseCors() 必须位于 app.UseRouting() 和 app.UseEndpoints() 之间。我把它放在中间再试一次,但后来又回到 400 错误。感谢您的尝试

标签: c# angular asp.net-core ssl ssl-certificate


【解决方案1】:

尝试在 UseRouting 和 UseAuthorization 之间放置 UseCors

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

试试这个 AddCors 的语法

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

如果它仍然不起作用,也可以删除它

'Access-Control-Allow-Origins':'*'

【讨论】:

  • 尝试了这两个想法,但仍然存在相同的问题,但谢谢。
【解决方案2】:

所以,我不一定能解释为什么这解决了我的问题,但它确实......

在 chrome 中我还去了:chrome://settings/security -> 管理证书 -> 删除 localhost 证书。

然后在 Visual Studio 终端中运行命令:dotnet dev-certs https --trust

经过以下工作

在 Startup.cs 中:

readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

在 startup.cs -> ConfigureServices:

services.AddCors(options =>
{
    options.AddPolicy(MyAllowSpecificOrigins,
        builder => builder.AllowAnyOrigin()
                           .AllowAnyMethod()
                           .AllowAnyHeader()
        );
});

在 Startup.cs -> 配置:

app.UseRouting();

app.UseAuthorization();
app.UseAuthentication();
// ... 
// UseCors must be between routing and endpoints
app.UseCors(MyAllowSpecificOrigins);
// ...
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-11
    • 2021-07-02
    • 2017-10-19
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    相关资源
    最近更新 更多