从 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 有效:
- policy.AllowAnyOrigin();
- policy.AllowAnyOrigin().AllowAnyMethod();
- policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader;
- policy.WithOrigins("https://localhost:4200").SetIsOriginAllowedToAllowWildcardSubdomains().AllowAnyMethod().AllowAnyHeader();
我还尝试创建一个 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();
我正在尝试从另一个用 Angular 开发的项目调用用 C# 开发的本地 api。
每次我尝试从 api 调用方法时,我都会收到此错误:
从源 'http://localhost:4200' 访问 'https://localhost:7239/users/getPrivacySettings' 处的 XMLHttpRequest 已被 CORS 策略阻止:请求的资源上不存在 'Access-Control-Allow-Origin' header。
我尝试将 api 中的核心策略更改为以下内容,其中 none 有效:
- policy.AllowAnyOrigin();
- policy.AllowAnyOrigin().AllowAnyMethod();
- policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader;
- policy.WithOrigins("https://localhost:4200").SetIsOriginAllowedToAllowWildcardSubdomains().AllowAnyMethod().AllowAnyHeader();
我还尝试创建一个 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();