Angular 8 下载文件时进度条无法按百分比显示剩余进度问题
问题根因与解决方案
根因1:HttpClient 请求未开启进度监听配置
你的 PostUpload 接口请求需要额外配置两个核心参数,才能正常向外抛出进度事件流,服务层的正确写法参考如下:
// data.service.ts 中的 PostUpload 方法示例 PostUpload(params: string, file: File): Observable<HttpEvent<any>> { const formData = new FormData(); formData.append('file', file); return this.http.post('你的业务接口地址', formData, { reportProgress: true, // 必须开启,才会生成进度事件 observe: 'events', // 必须设为 events,才会返回完整事件流而非直接返回响应体 responseType: 'blob' // 若接口返回文件,需要额外加这个配置 }) }
根因2:组件变更检测未触发
如果你的组件开启了 ChangeDetectionStrategy.OnPush 变更检测策略,直接给 progress 赋值不会触发视图重渲染,就会出现控制台能正常打印进度、但界面进度条不更新的问题。需要手动注入 ChangeDetectorRef 触发变更检测,修改订阅逻辑如下:
// 先在组件构造器注入 ChangeDetectorRef constructor(private cdr: ChangeDetectorRef) {} // 订阅部分修改 this._dataService.PostUpload(this.selectedoptions.toString(),this.fileToUpload) .subscribe((event: HttpEvent<any>) => { switch (event.type) { case HttpEventType.UploadProgress: this.progress = Math.round(event.loaded / event.total * 100); console.log(`Uploaded! ${this.progress}%`); this.cdr.detectChanges(); // 手动触发变更检测,更新视图 break; case HttpEventType.Response: console.log('Upload successfully created!', event.body); FileSaver.saveAs(event.body, this.fileToUpload.name + '.xlsx') setTimeout(() => { this.progress = 0; this.cdr.detectChanges(); }, 1500); } })
可选校验项
如果上述配置完成后问题仍然存在,可以做以下排查:
- 确认
event.total不为 undefined,部分后端没有返回Content-Length响应头时,会导致总大小读取失败,计算出来的进度直接为 100% - 如果你需要监听的是后端返回文件的下载进度而非上传文件的进度,把事件类型替换为
HttpEventType.DownloadProgress即可 - 问题复现截图:

内容的提问来源于stack exchange,提问作者ahmed barbary
相关产品推荐
相关产品推荐

