You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:15:41