文件上传进度检查文件是否在Angular 7中作为FormData发送? [英] File upload progress checking if file send as FormData in Angular 7?

查看:161
本文介绍了文件上传进度检查文件是否在Angular 7中作为FormData发送?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用HttpClient作为http使用以下代码在Angular 7中将文件作为FormData上传:

I uploading file as FormData in Angular 7 with this code using HttpClient as 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):

观察值根据消费者感兴趣的观察值确定request()的返回类型. 事件值将返回表示原始HttpEvent流的Observable<HttpEvent> ,默认情况下包括进度事件. response的值将返回Observable<HttpResponse<T>>,其中HttpResponse的T参数取决于responseType和任何可选提供的type参数. 主体的值将返回具有相同T主体类型的Observable<T> .

The observe value determines the return type of request(), based on what the consumer is interested in observing. A value of events will return an Observable<HttpEvent> representing the raw HttpEvent stream, including progress events by default. A value of response will return an Observable<HttpResponse<T>> where the T parameter of HttpResponse depends on the responseType and any optionally provided type parameter. A value of body will return an Observable<T> with the same T body type.

文档还指出,如果将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:

可以用以下两种方法之一调用此方法.可以直接将Ht​​tpRequest实例作为唯一参数传递,或者可以将方法作为第一个参数传递,将字符串URL作为第二个参数,将选项哈希作为第三个参数.

This method can be called in one of two ways. Either an HttpRequest instance can be passed directly as the only parameter, or a method can be passed as the first parameter, a string URL as the second, and an options hash as the third.

如果直接传递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发送?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆