具有多部分表单的 Angular 后请求内容类型错误

问题描述 投票:0回答:4

我正在使用以下函数将文件上传到具有角度 7 的 HttpClient 的服务器

  pushFileToStorage(productId, key, file: File): Observable<any> {
    let formdata: FormData = new FormData();

    formdata.append('prod', file);
    let url_ = '/admin5/api/v1/product/images/upload?';
    url_ += "productId=" + encodeURIComponent("" + productId) + "&";
    url_ += "kind=" + encodeURIComponent("" + key);

    return this.http.post(url_,formdata);
  }

我遇到的问题是 HttpClient 设置了错误的内容类型标头(application/json 而不是“multipart/form-data”),因此服务器无法读取文件。 这是我在开发者工具上看到的

enter image description here

enter image description here

知道我做错了什么吗? 谢谢

angular file-upload angular-httpclient
4个回答
15
投票

我刚刚发现我正在开发的项目有一个 HttpInterceptor,它默认向任何未设置内容类型的请求添加内容类型“application/json”。这就是问题所在。


2
投票

就我而言,我也使用 FormData。这背后的原因是 HTTP 拦截器,正如 @Maurizio Pozzobon 在接受的答案中所述。我正在使用 HTTP 拦截器,如下所示--

enter image description here

这里我的拦截器将我的令牌发送到每个 http 调用

'内容类型':'application/json;字符集=utf-8'

这造成了错误的内容类型错误。所以我需要绕过此类调用的拦截器。我从这里关注。

我导入HttpBackend

enter image description here

声明 HttpClient 变量

enter image description here

在构造函数中声明

enter image description here

现在使用这个 httpclient,我请求使用带有我的文件的 formdata 进行 Post api 调用。此 Http Post 调用绕过 Http Interceptor。我的问题就这样解决了。


0
投票

这是服务器标头,服务器使用 json 回答您,这是绝对正常的。像这样寻找库来加载图片更容易、更快捷 https://www.npmjs.com/package/angular-file-uploaderhttps://www.npmjs.com/package/angular-file


0
投票

我最近了解到,如果您的应用程序中有一个拦截器已经将内容类型作为 application/json 传递, 您必须添加条件来检查何时发送 FormData 的请求正文实例:(这是我所做的代码片段)

if(!(request.body instanceof FormData)) {
    authReq = request.clone({headers: request.headers
      // setting headers as required by the api 
      // on the swagger, a required field that accepts the X-Api-Version
      // so I had to set it here manually
      // also passing the Content-type of the application
      .set('X-Api-Version', '1')
      .set('Content-Type', 'application/json')
      .set('Authorization', `Bearer ${this.token}`)
    });
    return next.handle(authReq);
  }
  authReq = request.clone({headers: request.headers
    .set('X-Api-Version', '1')
    // when sending a FormData Request Body, the content-type is omitted 
    // because the FormData would set the content-type itself 
    // *** not so sure, will do more study *** 
    .set('Authorization', `Bearer ${this.token}`)
  });
  return next.handle(authReq);

因此,在请求标头中任何 FormData 类型 request.body 中,我删除了内容类型

© www.soinside.com 2019 - 2024. All rights reserved.