在 Angular 中发布内容类型 multipart/form-data

Posting with content type multipart/form-data in Angular

我正在创建一个 API 端点以在 .net core 2 中上传文件,如下所示

 [HttpPost("{userId}/files")]
    public async Task<IActionResult> AddUserFile([FromRoute]string userId)
    {
        var file = Request.Form.Files.FirstOrDefault();

        var myFile = new MyFiles
        {
            FilePath = await UploadFile(file), // save the file and return url
            UserId = userId,
            FileName = Request.Form["fileName"],
            Description = Request.Form["description"]
        };

        // todo save file to database

        return Ok(myFile);
    }

我使用 Postman 测试了这个端点,它按预期工作。

当尝试从 Angular 应用程序调用此端点时,如下所示

onAddFile(form: NgForm) {

   const formData: FormData = new FormData();
   formData.append('', this.selectedFile);
   formData.append('fileName', form.value.fileName);
   formData.append('description', form.value.description);
   formData.append('userId', this.userId);

   const headers = new Headers();
   headers.append('accept-language', 'en');
   headers.append('Content-Type', 'multipart/form-data');
   headers.append('Authorization', `Bearer ${token}`);

   this.http.post(
     `https://localhost:44339/api/admin/users/${this.userId}/files`,
     formData,
     new RequestOptions({ headers: headers })
   ).subscribe(result => {
     console.log(result);
   });
 }

我收到以下错误

:44339/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files:1 POST https://localhost:44339/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files

edit:1 XMLHttpRequest cannot load https://localhost:44339/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 500.

这是从 Angular 应用

捕获的请求 header
:authority:localhost:44339
:method:POST
:path:/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files
:scheme:https
accept:application/json
accept-encoding:gzip, deflate, br
accept-language:en-US,en;q=0.8,ar;q=0.6
authorization:Bearer eyJhbGciOiJIU.........
content-length:21531
content-type:multipart/form-data;
origin:http://localhost:4200
referer:http://localhost:4200/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/edit

和我的请求负载

------WebKitFormBoundaryqB4rbqWsrra0gwhi
Content-Disposition: form-data; name=""; filename="2017-08-22_21-56-02.png"
Content-Type: image/png


------WebKitFormBoundaryqB4rbqWsrra0gwhi
Content-Disposition: form-data; name="fileName"

er
------WebKitFormBoundaryqB4rbqWsrra0gwhi
Content-Disposition: form-data; name="description"

df
------WebKitFormBoundaryqB4rbqWsrra0gwhi
Content-Disposition: form-data; name="userId"

c6d15e43-00b9-4eda-bac8-635f6017fec9
------WebKitFormBoundaryqB4rbqWsrra0gwhi--

在尝试找出问题时,我注意到只有当请求 content-typemultipart/form-data 时才会发生这种情况,在这种情况下我必须使用它才能上传文件。

我在这里遗漏了什么,我是在 angular 中做错了什么,还是我在服务器端 API 遗漏了配置?


编辑:

启动时的cors配置

  app.UseCors(builder =>
                builder
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowAnyOrigin()
                    .AllowCredentials()
            );

您必须按照 A.Tim 的建议在后端启用 CORS。以下是 Java 中基于 Spring 的应用程序的完成方式。

public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry corsRegistry) {
            corsRegistry.addMapping("/**").allowedMethods("*").allowedHeaders("*").allowedOrigins("*");
        }
    };
}

我认为您在 Angular 的 http url 中有错别字:

https://localhost:44339/api/admin/users/${this.userId}/files

应该是(注意端口)

https://localhost:4200/api/admin/users/${this.userId}/files

或者更好的是,使用相对 url 以便自动计算主机。

如果您实际上是在本地主机中运行这两个应用程序,请确保端口 44339 中的应用程序已配置 CORS。

Chrome 抛出此错误,因为您正在向不同端口中的主机发送请求。 请注意,仅出于测试目的,您可以在 Chrome 中暂时在本地禁用此安全措施, 如果你有 Windows 按 Win+R 然后执行:

chrome --disable-web-security --user-data-dir

(您必须先关闭所有 Chrome 个实例,包括 Postman)

我终于解决了这个问题,解决方法是从 header

中删除内容类型

headers.delete('Content-Type');

不要留空否则会出错

Incorrect Content-Type: , multipart/form-data; boundary