问题描述
我使用 HttpClient
作为 http
:
sendImageFile(subUri: string, id: number, fileToUpload: File): Observable<any> {
const formData: FormData = new FormData();
formData.append('file', fileToUpload, fileToUpload.name);
formData.append('photoalbum_id', id.toString() );
// ... some other .append()
const customHeaders = new HttpHeaders({
'Authorization': 'Bearer' + localStorage.getItem('token'),
'Accepted-Encoding': 'application/json'
});
const customOptions = {
headers: customHeaders,
reportProgress: true
};
return this.http.post(this.url, formData, customOptions)
.pipe(
map( (event: HttpEvent<any>) => this.getEventMessage(event, fileToUpload)),
tap(message => this.showProgress(message)),
// last(),
catchError(this.handleError));
}
private showProgress(message: any) {
// ...
}
private getEventMessage(event: HttpEvent<any>, file: File) {
// ...
}
这里的主要问题是不检查上传,因为文件是上传 FormData
的一部分,所以在上传完成之前我没有得到任何反馈.
The main problem is here isn't checking the uploading because the file is uploaded part of the FormData
so I don't get any feedback until the upload is finished.
我对这个进度检查有点困惑.我必须将文件上传为 FormData.这种情况下如何查看上传进度?
I'm a little bit confused about this progress checking. I must to upload file as FormData. How can I check the upload progress in this case?
推荐答案
答案在于 HttpClient
的实现.通过 HttpClient.post
方法创建的所有请求默认将 observe
属性设置为 body
.参见 这个 HttpClient.post 方法详情.这意味着:即使您成功地将 reportProgress
设置为 true
,生成的 observable 正在观察请求正文而不是 HttpEvents
.来自 文档(重点是我的):
The answer lies in HttpClient
's implementation. All requests created via the HttpClient.post
method default the observe
property to body
. See this HttpClient.post method for details. What this means is: even though you successfully set reportProgress
to true
, the resulting observable is observing the request body instead of the HttpEvents
. From the docs (emphasis mine):
observe 值决定了 request() 的返回类型,基于消费者对观察的兴趣.事件的值将返回一个 Observable
表示原始 HttpEvent 流,默认情况下包括进度事件.response 的值将返回 Observable>
,其中 HttpResponse 的 T 参数取决于 responseType 和任何可选提供的类型参数.body 的值将返回一个 Observable
具有相同的 T 体类型.
文档还指出,如果您将 HttpRequest
实例传递给 request
,它将默认返回 HttpEvent
流的可观察对象:
The documentation also notes that if you pass an HttpRequest
instance to request
, it will return an observable of the HttpEvent
stream by default:
可以通过以下两种方式之一调用此方法.可以直接将 HttpRequest 实例作为唯一参数传递,也可以将方法作为第一个参数传递,将字符串 URL 作为第二个参数传递,将选项哈希作为第三个参数传递.
如果直接传入一个HttpRequest对象,会返回一个原始HttpEvent流的Observable.
If a HttpRequest object is passed directly, an Observable of the raw HttpEvent stream will be returned.
因此,观察 HttpEvent
流的最简单方法是直接传递一个 HttpRequest
对象,如下所示:
So, the easiest way to observe the HttpEvent
stream is to pass an HttpRequest
object directly as noted:
sendImageFile(subUri: string, id: number, fileToUpload: File): Observable<any> {
const formData: FormData = new FormData();
formData.append('file', fileToUpload, fileToUpload.name);
formData.append('photoalbum_id', id.toString());
// ... some other .append()
const customHeaders = new HttpHeaders({
'Authorization': 'Bearer' + localStorage.getItem('token'),
'Accepted-Encoding': 'application/json'
});
const customOptions = {
headers: customHeaders,
reportProgress: true,
};
const req = new HttpRequest('POST', this.url, formData, customOptions);
// Call HttpClient.request with an HttpRequest as only param to get an observable of HttpEvents
return this.http.request(req)
.pipe(
map((event: HttpEvent<any>) => this.getEventMessage(event)),
catchError(this.handleError));
}
private getEventMessage(event: HttpEvent<any>) {
// We are now getting events and can do whatever we want with them!
console.log(event);
}
我在本地存储库上测试了这个重构后的代码,效果很好.
I tested this refactored code on a local repository and it worked just fine.
这篇关于文件上传进度检查文件是否在 Angular 7 中作为 FormData 发送?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!