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

时间:2017-09-15 13:34:24

标签: angular cors multipartform-data asp.net-core-webapi asp.net-core-2.0

我正在创建一个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 /管理/用户/ c6d15e43-00b9-4eda-bac8-635f6017fec9 /文件:1   POST   https://localhost:44339/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files

     

编辑:1 XMLHttpRequest无法加载https://localhost:44339/api/admin/users/c6d15e43-00b9-4eda-bac8-635f6017fec9/files。   No&#39; Access-Control-Allow-Origin&#39;标题出现在请求的上   资源。起源&#39; http://localhost:4200&#39;因此是不允许的   访问。响应的HTTP状态代码为500。

enter image description here

这是来自Angular应用程序的捕获请求标头

: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时才会发生这种情况,我必须在这种情况下使用该文件才能上传文件。

我在这里缺少什么,我在角度方面做错了什么,或者我错过了服务器端API中的配置?

修改

启动时的cors配置

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

3 个答案:

答案 0 :(得分:1)

我最终能够解决这个问题,修复方法是从标题中删除内容类型

WriteObject

请勿将其留空,否则会导致错误

  

不正确的内容类型:,multipart / form-data;边界

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

我相信你在Angular的http url:

中有一个拼写错误
  

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

应该是(注意端口)

  

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

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

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

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

  

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

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