从 Angular 项目调用本地 c# api 时 CORS 出错

Error with CORS when calling local c# api from an Angular project

我正在尝试从另一个用 Angular 开发的项目调用用 C# 开发的本地 api。

每次我尝试从 api 调用方法时,我都会收到此错误:

从源 'http://localhost:4200' 访问 'https://localhost:7239/users/getPrivacySettings' 处的 XMLHttpRequest 已被 CORS 策略阻止:请求的资源上不存在 'Access-Control-Allow-Origin' header。

我尝试将 api 中的核心策略更改为以下内容,其中 none 有效:

我还尝试创建一个 web.config 文件(它不是与项目一起创建的)并在那里添加配置目录,但它也什么也没做。

<system.webServer>
      <httpProtocol>
          <customHeaders>
              <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
              <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" />
          </customHeaders>
      </httpProtocol>
      <rewrite>
          <outboundRules>
              <clear />
              <rule name="AddCrossDomainHeader">
                  <match serverVariable="RESPONSE_Access_Control_Allow_Origin" pattern=".*" />
                  <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
                      <add input="{HTTP_ORIGIN}" pattern="(http(s)?://((.+\.)?domain1\.com|(.+\.)?domain2\.com|(.+\.)?domain3\.com))" />
                  </conditions>
                  <action type="Rewrite" value="{C:0}" />
              </rule>
          </outboundRules>
      </rewrite>
      
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
  </system.webServer>

这是我的 program.cs 文件

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using System.Text;

var builder = WebApplication.CreateBuilder(args);
string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
// Add services to the container.

builder.Services.AddControllers();


// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();


builder.Services.AddHttpContextAccessor();
builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins, policy =>
    {
        policy.WithOrigins("https://localhost:4200").SetIsOriginAllowedToAllowWildcardSubdomains().AllowAnyMethod().AllowAnyHeader();
    });
});

builder.Services.AddSwaggerGen(options =>
{
    options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
    {
        Description = "Standard Authorization header using the Bearer scheme (\"bearer {token}\")",
        In = ParameterLocation.Header,
        Name = "Authorization",
        Type = SecuritySchemeType.ApiKey
    });

    options.OperationFilter<SecurityRequirementsOperationFilter>();
});
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8
                .GetBytes("my top secret key")),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

DependencyInjection dependencyInjection = new(builder.Configuration);
dependencyInjection.InjectDependencies(builder.Services);

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}


app.UseHttpsRedirection();
app.UseCors();

app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();

app.Run();

欢迎任何帮助。

问题是您没有指定应在 app.UseCors 方法上使用的 CORS 策略,如文档 here 中所示;对于您的情况,这将是:

app.UseCors(MyAllowSpecificOrigins);

此外,我建议您将 CORS 策略更改为以下内容:

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins, policy => policy.WithOrigins("http://localhost:4200").AllowAnyHeader().AllowAnyMethod());
});

这是因为您不需要(至少现在)允许策略使用通配符子域。

作为奖励,您还可以设置默认的 CORS 策略,如文档 here 中所示。

builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy => policy.WithOrigins("http://localhost:4200").AllowAnyHeader().AllowAnyMethod());
});

// ...

app.UseCors();