如何使用 Angular/Laravel 取消文件上传到 S3?

问题描述 投票:0回答:1

我正在使用 Angular 和 Laravel 构建文件上传。我希望能够在文件上传过程中取消该文件上传。到目前为止它是有效的,但我不太有信心,所以我想确保我正确理解了逻辑。如果没有,请寻找更好的解决方案。

到目前为止,我有一个用于文件上传的 Angular 组件,它将向我的 API 发出 HTTP POST 请求,以使用 laravel Storage 外观和 putFileAs() 上传文件。

根据我的理解(我是 Laravel 和 Angular 的新手),我将文件流式传输到我的后端,并使用 putFileAs() 将上传流式传输到 S3。因此,如果我想取消上传到 S3,我只需要取消订阅我的角度组件中的 observable 即可。

我的理解正确吗?我的逻辑有漏洞吗?

处理上传的 Angular 函数

uploadFile(file: File){
  this.progressBar = true;
  this.uploading = this.fileService.uploadFile(file)
    .pipe(finalize((res) => {
      console.log('Upload success!');
    })
    .subscribe(res => {
      this.progressBar = false;
    });
}


cancelUpload(){
  if(this.uploading){
    this.uploading.unsubscribe();
  }
  this.progressBar = false;
}

处理上传的控制器函数。

public function uploadFile(Request $request){
  $data = $request->input();
  $file = $request->file('file');

  $res = Storage::disk('s3')->putFileAs('/somePath/', $file, $data['filename']);

  if($res){
    return response()->json($res, 200);
  } else {
    return response()->json($res, 422);
  }
}
angular laravel amazon-s3
1个回答
0
投票

我认为这个逻辑的 Angular 部分是正确的,但是我可以在不知道

FileUploadService
类如何工作的情况下提出以下建议吗?这里的关键考虑因素是使用 subject 取消请求,以及从 httpClient 添加 reportProgress。

对于 Laravel,也许添加一个 try catch 块来捕获异常,并可能添加验证来检查文件的有效性,因为 Angular 代码本身可能没有这些验证。

文件上传服务

export class FileUploadService {
  private cancelUpload$ = new Subject<void>();

  constructor(private http: HttpClient) {}

  // File upload function with progress tracker
  uploadFile(file: File): Observable<any> {
    const formData = new FormData();
    formData.append('file', file);

    const headers = new HttpHeaders();
    const url = 'test-endpoint'; 

    return this.http.post(url, formData, {
      headers: headers,
      reportProgress: true,
      observe: 'events',
    }).pipe(
      takeUntil(this.cancelUpload$)
    );
  }

  cancelUpload() {
    this.cancelUpload$.next();
  }
}

组件

export Class Component {
      uploadProgress: number = 0;
      uploading: boolean = false;
      uploadSubscription: any;
      fileUploadService = inject(FileUploadService);

      onUpload(file: File) {
        this.uploading = true;

          // Start file upload
          this.uploadSubscription = this.fileUploadService.uploadFile(file)
            .subscribe({
              next: event => {
                // Calculate progress
                if (event.type === HttpEventType.UploadProgress) {
                  this.uploadProgress = Math.round((100 * event.loaded) / event.total!);
                } else if (event instanceof HttpResponse) {
                  console.log('Upload complete:', event.body);
                  this.uploading = false;
                }
              },
              error: error => {
                console.error('Upload error:', error);
                this.uploading = false;
              }
           })
      }

      onCancelUpload() {
        this.fileUploadService.cancelUpload(); // Trigger cancellation in the service
        this.uploading = false;
        this.uploadProgress = 0;
        if (this.uploadSubscription) {
          this.uploadSubscription.unsubscribe(); 
        }
      }
    }
© www.soinside.com 2019 - 2024. All rights reserved.