Angular 14上传时reportProgress仅返回完成事件,无法获取进度反馈
Angular 14 文件上传无法获取进度反馈的解决办法
问题描述
使用Angular 14开发自定义上传服务,已在请求配置中开启reportProgress: true和observe: 'events',但订阅请求事件后仅能收到上传完成的响应事件,无法获取上传过程中的进度反馈。
解决方案
1. 明确区分事件类型,处理上传进度
当前代码仅打印所有事件,未针对上传进度事件做单独处理。需要导入HttpEventType并判断事件类型,提取进度数据:
首先在组件中导入HttpEventType:
import { HttpEventType } from '@angular/common/http';
然后修改订阅逻辑,区分进度事件与完成事件:
this.http.uploadFile(formData).subscribe((event) => { switch (event.type) { case HttpEventType.UploadProgress: // 计算并输出上传进度百分比 const percentDone = event.total ? Math.round(100 * event.loaded / event.total) : 0; console.log(`上传进度:${percentDone}%`); // 可将进度值绑定到页面展示 break; case HttpEventType.Response: console.log('上传完成', event.body); // 处理上传完成后的业务逻辑 break; } });
2. 检查请求方法与后端适配
当前服务使用put方法上传文件,部分后端框架默认仅支持post方法处理文件上传。若后端未配置put方法的文件上传支持,可能导致进度事件无法触发。可以尝试将请求方法改为post:
修改HttpService中的请求代码:
return this.http.post(`${environment.backend}/file-upload/${type}`, formData, { reportProgress: true, observe: 'events', });
3. 确认后端支持流式处理上传
如果后端在接收文件时立刻返回响应(而非流式处理上传过程),浏览器无法捕获中间进度数据。需确保后端在处理文件上传时,支持分块接收并允许浏览器获取进度更新。
4. 排查Http拦截器的配置冲突
若项目中存在Http拦截器,需检查拦截器是否修改了reportProgress或observe参数,避免覆盖上传进度监听的关键配置。
修改后的完整代码示例
自定义上传服务(HttpService)
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { environment } from '@env'; @Injectable({ providedIn: 'root' }) export class HttpService { constructor(private http: HttpClient) {} public uploadFile(formData: FormData, type: 'single' | 'multiple' = 'single') { return this.http.post(`${environment.backend}/file-upload/${type}`, formData, { reportProgress: true, observe: 'events', }); } }
组件代码(HttpComponent)
import { Component, OnInit } from '@angular/core'; import { HttpService } from './http.service'; import { NzCardModule } from 'ng-zorro-antd/card'; import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzUploadFile, NzUploadModule } from 'ng-zorro-antd/upload'; import { HttpEventType } from '@angular/common/http'; @Component({ selector: 'http', standalone: true, imports: [NzCardModule, NzUploadModule, NzButtonModule], templateUrl: './http.component.html', }) export class HttpComponent implements OnInit { public fileList: NzUploadFile[] = []; public uploadProgress = 0; constructor(private http: HttpService) {} ngOnInit(): void {} public handleUpload = (file: NzUploadFile, fileList: NzUploadFile[]) => { const formData = new FormData(); formData.append('file', file as unknown as File); this.uploadProgress = 0; this.http.uploadFile(formData).subscribe((event) => { switch (event.type) { case HttpEventType.UploadProgress: if (event.total) { this.uploadProgress = Math.round(100 * event.loaded / event.total); console.log(`当前上传进度:${this.uploadProgress}%`); } break; case HttpEventType.Response: console.log('上传完成', event.body); // 此处可添加上传完成后的状态更新逻辑 break; } }); return false; }; }
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

