取消文件上传:Multer,MongoDB

Cancel File Upload: Multer, MongoDB

我似乎找不到关于如何使用 Mongo、NodeJS 和 Angular 取消文件上传的任何最新答案 .我只看过一些关于如何删除文件的教程,但那是 NOT 我要找的东西。我希望能够通过单击前端上的按钮来取消文件上传过程。

我使用 Mongoose、Multer 和 GridFSBucket 包 将我的文件直接存储到 MongoDB 中的 chuncks。我知道我可以通过 unsubscribing 从负责前端上传的 subsribable 停止前端的文件上传过程,但上传过程继续在后台进行 -当我取消订阅时结束**(是的,我已经双重和三次检查。所有的块都在不断上传,直到文件完全上传。)

这是我的Angular代码:

  ngOnInit(): void {
    // Upload the file.
    this.sub = this.mediaService.addFile(this.formData).subscribe((event: HttpEvent<any>) => {
      console.log(event);
      switch (event.type) {
        case HttpEventType.Sent:
          console.log('Request has been made!');
          break;
        case HttpEventType.ResponseHeader:
          console.log('Response header has been received!');
          break;
        case HttpEventType.UploadProgress:
          // Update the upload progress!
          this.progress = Math.round(event.loaded / event.total * 100);
          console.log(`Uploading! ${this.progress}%`);
          break;
        case HttpEventType.Response:
          console.log('File successfully uploaded!', event.body);
          this.body = 'File successfully uploaded!';
      }
    },
    err => {
      this.progress = 0;
      this.body = 'Could not upload the file!';
    });
  }


  **CANCEL THE UPLOAD**
  cancel() {
    // Unsubscribe from the upload method.
    this.sub.unsubscribe();
  }

这是我的 NodeJS (Express) 代码:

...

// Configure a strategy for uploading files.
const multerUpload = multer({ 
    // Set the storage strategy.
    storage: storage,
    // Set the size limits for uploading a file to 120MB.
    limits: 1024 * 1024 * 120,
    // Set the file filter.
    fileFilter: fileFilter
}); 

// Add new media to the database.
router.post('/add', [multerUpload.single('file')], async (req, res)=>{
    return res.status(200).send();
});

取消上传而不在数据库中留下任何块的正确方法是什么?

尝试使用try catch方式。

有两种方法可以完成。

  1. 通过调用一个 api,它将当前上传的文件作为参数,然后在后端执行删除和清除服务器上存在的块的步骤

  2. 异常处理
    通过发送文件大小作为验证,如果后端 api 已收到完全符合其大小的文件,则应保留该文件,或者如果收到的文件大小较小,这是由于取消了上传 bin然后执行清除步骤,您只需获取文件 chuck 的 id 和 mongoose db 并清除它。

所以我已经尝试了 2 天来弄清楚这个问题,我相信我已经找到了一个令人满意的解决方案:

首先,为了取消文件上传并删除任何已经上传到MongoDB的块,您需要调整fileFilter 在您的 multer 配置 中以这种方式检测请求是否已中止以及上传流是否已结束。然后使用 fileFilter 的回调抛出错误来拒绝上传:

// Adjust what files can be stored.
const fileFilter = function(req, file, callback){
    console.log('The file being filtered', file)

    req.on('aborted', () => {
        file.stream.on('end', () => {
            console.log('Cancel the upload')
            callback(new Error('Cancel.'), false);
        });
        file.stream.emit('end');
    })
}

注意:取消文件上传时,您必须等待更改显示在您的数据库中。在从数据库中删除已取消的文件之前,必须首先上传已经发送到数据库的块。这可能需要一段时间,具体取决于您的网速和取消上传前发送的字节数。

最后,您可能想在后端设置一个路由,以删除尚未完全上传到数据库的文件中的任何块(由于上传过程中可能发生的一些错误)。为此,您需要从 .chunks 集合 () 中获取所有文件 ID,并 将块已部分上传到数据库的文件 ID 从已完全上传的文件ID。然后,您需要对这些 ID 调用 GridFSBucket 的 delete() 方法,以去除冗余块。此步骤完全是可选的,并且出于数据库维护的原因。