You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core持续出现No Access-Control-Allow-Origin Header错误求助

CORS错误排查与解决

问题现象

尝试多种方法(包括Stack Overflow方案)后,通过HTML页面调用API仍触发CORS错误:

Access to XMLHttpRequest at '[api location]' from origin '[web app location]' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
  • Swagger和Postman调用API正常(推测Swagger与API同域)
  • Postman能收到Access-Control-Allow-Origin响应头

相关代码

Program.cs

using Azure.Identity;
using [project name].Middleware;

var builder = WebApplication.CreateBuilder(args);

var keyVaultEndpoint = new Uri(Environment.GetEnvironmentVariable("VaultUri"));
builder.Configuration.AddAzureKeyVault(keyVaultEndpoint, new DefaultAzureCredential());

// 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.AddSwaggerGen();

var app = builder.Build();

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

app.UseMiddleware<ApiKeyMiddleware>();
app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

前端JS/HTML代码

<script>
// WARNING: For POST requests, body is set to null by browsers.

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "[api url]");
xhr.setRequestHeader("XApiKey", "[api key]");
xhr.setRequestHeader("Origin", "https://[web app site]");
xhr.setRequestHeader("Access-Control-Allow-Credentials", "true");
xhr.send();
</script>

API接口代码

[HttpPost("[Name]")]
public IEnumerable<[Model]> [Name]([FromServices] IConfiguration Configuration, [params])
{
    [sql stuff]
    Response.Headers.Add("Access-Control-Allow-Origin", "[web app]");
    Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    Response.Headers.Add("Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS");
    Response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization, X-Requested-With");

    return Enumerable.Range(1, 1).Select(index => new [Model]
    {
        output = "Updated"
    });
}

补充问题

在Program.cs中配置允许任意源时,系统提示Access-Control-Allow-Origin不能使用通配符。


解决方案

核心问题:预检请求未被正确处理

浏览器发送的OPTIONS预检请求不会进入你的API接口方法,所以你在接口里添加的CORS头根本不会生效,这才是报错的根源。Swagger同域无需预检,Postman不会触发浏览器的CORS机制,所以都正常。

正确配置步骤

  1. 添加CORS服务配置
    在Program.cs的builder.Services.AddControllers();之前添加CORS配置:
// 配置允许的源、方法和头
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowSpecificOrigin",
        policy =>
        {
            policy.WithOrigins("https://[web app site]") // 替换为你的前端域名
                  .AllowAnyHeader()
                  .AllowAnyMethod()
                  .AllowCredentials(); // 因为你用了withCredentials = true
        });
});
  1. 启用CORS中间件
    确保CORS中间件在管道中的顺序正确,要放在UseAuthorization之前,UseHttpsRedirection之后:
app.UseHttpsRedirection();
// 启用CORS,使用上面定义的策略
app.UseCors("AllowSpecificOrigin");
app.UseAuthorization();
  1. 移除接口内的CORS头代码
    接口方法里手动添加的CORS头会和中间件的配置冲突,直接删掉:
// 删掉这些代码
// Response.Headers.Add("Access-Control-Allow-Origin", "[web app]");
// Response.Headers.Add("Access-Control-Allow-Credentials", "true");
// Response.Headers.Add("Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS");
// Response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization, X-Requested-With");
  1. 前端代码调整
    不需要手动设置Access-Control-Allow-Credentials请求头,这是响应头,浏览器会自动处理;Origin头浏览器也会自动发送,不需要手动添加:
<script>
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "[api url]");
xhr.setRequestHeader("XApiKey", "[api key]");
// 去掉下面两行
// xhr.setRequestHeader("Origin", "https://[web app site]");
// xhr.setRequestHeader("Access-Control-Allow-Credentials", "true");
xhr.send();
</script>

为什么通配符不行?

当使用withCredentials = true时,Access-Control-Allow-Origin不能用*通配符,必须指定具体的前端域名,这是浏览器的安全限制,所以之前配置通配符会报错。


内容的提问来源于stack exchange,提问作者user19575939

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 13:54:21