我正在使用 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 部分是正确的,但是我可以在不知道
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();
}
}
}