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

.NET 6 Web API与React文件上传的CORS及代理问题排查

React上传文件到.NET 6 Web API遇CORS/代理问题

问题现象

  • Postman调用文件上传接口正常,但Swagger和React调用均失败
  • 无文件上传的POST、GET、PUT接口均可正常使用
  • React网络面板报错:Could not proxy request /api/Employee/SaveFile from localhost:3000 to "https://127.0.0.1:7224/" (ECONNREFUSED)

已尝试操作

  • 在package.json配置代理:"proxy": "https://127.0.0.1:7224/"
  • 修改React启动命令:"start": "cross-env DANGEROUSLY_DISABLE_HOST_CHECK=true react-scripts start"
  • React代码尝试过带/不带headers的写法

代码片段

React上传代码

imageUpload = (e) => {
    e.preventDefault();

    const formData = new FormData();
    formData.append("file", e.target.files[0], e.target.files[0].name);

    fetch('/api/Employee/SaveFile', {
        method: 'POST',
        body: formData,
        headers : { 
            'Content-Type': 'multipart/form-data',
            'Accept': 'application/json, text/plain'
           }
    })
        .then(res => res.json())
        .then(data => {
            this.setState({ PhotoFileName: data });
        })
}

.NET 6 Program.cs CORS配置

//Enable CORS
builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "orgEmpPolicy",
                policy =>
                {
                    policy.WithOrigins("http://localhost:3000/", "http://192.168.1.9:3000/", "http://127.0.0.1:3000/")
                    .WithHeaders(HeaderNames.ContentType)
                    .WithMethods("PUT", "DELETE", "GET", "PATCH", "POST");
                });
});


var app = builder.Build();

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

app.UseRouting();

app.UseCors("orgEmpPolicy");

.NET 6 控制器代码

[HttpPost]
[Route("SaveFile")]        
public JsonResult SaveFile()
{
    try
    {
        var httpRequest = Request.Form;
        var postedFile = httpRequest.Files[0];
        string filename = postedFile.FileName;


        if (string.IsNullOrWhiteSpace(_env.WebRootPath))
        {
            _env.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
        }

        var uploads = Path.Combine(_env.WebRootPath, "Photos");
        var filePath = Path.Combine(uploads, postedFile.FileName);

        if (!Directory.Exists(uploads))
            _ = Directory.CreateDirectory(Path.GetDirectoryName(filePath));

        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            stream.CopyTo(stream);
        }

        return new JsonResult(filename);
    }
    catch (Exception ex)
    {
        return new JsonResult(ex.Message);
    }
}

调试环境

Visual Studio 2022调试Web API,VS Code调试React


解决方案

1. 修复React请求的Content-Type问题

使用FormData上传文件时,禁止手动设置Content-Type: multipart/form-data,浏览器会自动生成包含boundary的正确请求头,手动设置会丢失boundary信息,导致后端无法解析表单,同时触发CORS预检失败。

修改后的React代码:

imageUpload = (e) => {
    e.preventDefault();

    const formData = new FormData();
    formData.append("file", e.target.files[0], e.target.files[0].name);

    fetch('/api/Employee/SaveFile', {
        method: 'POST',
        body: formData,
        headers : { 
            'Accept': 'application/json, text/plain'
           }
    })
        .then(res => res.json())
        .then(data => {
            this.setState({ PhotoFileName: data });
        })
        .catch(err => console.error('上传失败:', err));
}

2. 修正CORS配置的Origin后缀

WithOrigins中的地址不能带斜杠,否则Origin匹配失效。修改Program.cs的CORS配置:

policy.WithOrigins("http://localhost:3000", "http://192.168.1.9:3000", "http://127.0.0.1:3000")

开发环境可临时放宽头限制(生产环境需按需配置):

policy.WithOrigins("http://localhost:3000", "http://192.168.1.9:3000", "http://127.0.0.1:3000")
      .AllowAnyHeader()
      .AllowAnyMethod();

3. 校验代理与API地址一致性

  • 查看Web API项目的Properties/launchSettings.json,确认applicationUrl是否为https://127.0.0.1:7224,避免端口/协议不匹配导致连接拒绝
  • 若API使用HTTP而非HTTPS,代理地址需改为http://127.0.0.1:xxxx

4. 修复控制器文件流错误

控制器中stream.CopyTo(stream)会导致无限循环,应改为:

postedFile.CopyTo(stream);

5. 让Swagger支持文件上传

在控制器方法上添加特性,让Swagger识别请求类型:

[HttpPost]
[Route("SaveFile")]
[Consumes("multipart/form-data")]      
public JsonResult SaveFile()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:07:16