Angular 14中如何在文件上传时取消POST请求
实现Angular文件上传的取消功能
要实现单个文件上传的取消功能,核心是为每个上传请求绑定取消控制器,并维护每个文件的独立上传状态,以下是具体实现步骤:
1. 定义上传项状态结构
创建一个接口来存储每个文件的上传相关信息,包括文件本身、上传状态、进度和取消控制器:
interface UploadItem { file: File; relativePath: string; isUploading: boolean; progress: number; abortController?: AbortController; }
在组件中替换原有的files数组为这个带状态的数组(根据你的拖放逻辑初始化):
uploadItems: UploadItem[] = []; // 拖放文件后初始化上传项 initUploadItems(files: FileList) { this.uploadItems = Array.from(files).map(file => ({ file: file, relativePath: file.name, // 替换为你的文件路径逻辑 isUploading: false, progress: 0 })); }
2. 修改上传方法,绑定取消控制器
更新uploadFiles方法,为每个文件单独发起请求,并通过AbortController绑定取消信号,同时跟踪上传进度:
import { HttpClient, HttpHeaders, HttpEventType } from '@angular/common/http'; import { tap, catchError, EMPTY } from 'rxjs'; // ... uploadFiles() { this.uploadItems.forEach(item => { if (item.isUploading) return; item.isUploading = true; const abortController = new AbortController(); item.abortController = abortController; const formData = new FormData(); formData.append('excel', item.file); const headers = new HttpHeaders({ 'x-request-id': 'file_upload_' + new Date().getTime(), }); this.http.post('http://localhost:8090/service/fileprocess/upload', formData, { headers: headers, responseType: 'json', signal: abortController.signal, // 绑定取消信号 reportProgress: true, // 开启进度跟踪 observe: 'events' // 监听上传事件 }).pipe( tap(event => { // 更新上传进度 if (event.type === HttpEventType.UploadProgress) { item.progress = Math.round(100 * (event.loaded / (event.total || 1))); } }), catchError(err => { item.isUploading = false; // 忽略取消请求的错误 if (err.name === 'AbortError') { return EMPTY; } return this.handleError(err); }) ).subscribe({ next: res => { if (res.type === HttpEventType.Response) { item.isUploading = false; // 处理上传成功逻辑 } } }); }); }
3. 实现取消上传方法
通过索引找到对应的上传项,调用取消控制器的abort()方法中断请求,并更新状态:
stopThisUpload(index: number) { const item = this.uploadItems[index]; if (item.abortController) { item.abortController.abort(); item.isUploading = false; item.progress = 0; // 重置进度 } }
4. 更新模板绑定状态
修改模板,将原有的全局状态替换为每个上传项的独立状态:
<div class="row mt-1" *ngFor="let item of uploadItems; let indexOfelement=index;"> <div class="col-lg-1"> <p-progressSpinner *ngIf="item.isUploading"></p-progressSpinner> </div> <div class="col-lg-3"> {{ item.relativePath }} </div> <div class="col-lg-6"> <p-progressBar *ngIf="item.isUploading" [value]="item.progress"></p-progressBar> </div> <div class="col-lg-2 text-end"> <i class="fa fa-ban" *ngIf="item.isUploading" (click)="stopThisUpload(indexOfelement)"></i> </div> </div>
关键说明
- 使用
AbortController是现代浏览器和Angular推荐的取消HTTP请求方式,它会真正中断底层请求,比单纯取消订阅更高效。 - 每个文件维护独立的上传状态,避免全局状态导致的混淆。
- 取消请求时会触发
AbortError,需要在错误处理中忽略该错误,避免向用户展示错误提示。
内容的提问来源于stack exchange,提问作者Tanzeel
相关产品推荐
相关产品推荐

