我正在使用以下函数将文件上传到具有角度 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”),因此服务器无法读取文件。 这是我在开发者工具上看到的
知道我做错了什么吗? 谢谢
我刚刚发现我正在开发的项目有一个 HttpInterceptor,它默认向任何未设置内容类型的请求添加内容类型“application/json”。这就是问题所在。
就我而言,我也使用 FormData。这背后的原因是 HTTP 拦截器,正如 @Maurizio Pozzobon 在接受的答案中所述。我正在使用 HTTP 拦截器,如下所示--
这里我的拦截器将我的令牌发送到每个 http 调用
'内容类型':'application/json;字符集=utf-8'
这造成了错误的内容类型错误。所以我需要绕过此类调用的拦截器。我从这里关注。
我导入HttpBackend
声明 HttpClient 变量
在构造函数中声明
现在使用这个 httpclient,我请求使用带有我的文件的 formdata 进行 Post api 调用。此 Http Post 调用绕过 Http Interceptor。我的问题就这样解决了。
这是服务器标头,服务器使用 json 回答您,这是绝对正常的。像这样寻找库来加载图片更容易、更快捷 https://www.npmjs.com/package/angular-file-uploader 或https://www.npmjs.com/package/angular-file
我最近了解到,如果您的应用程序中有一个拦截器已经将内容类型作为 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 中,我删除了内容类型