0

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

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

这是我的角代码

  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();
});

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

4

2 回答 2

0

尝试使用 try catch 方式。

有两种方法可以做到。

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

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

于 2020-11-13T18:13:26.127 回答
0

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

首先,为了取消文件上传并删除任何已经上传到 MongoDB 的块,您需要调整 multer 配置中的 fileFilter 以检测请求是否已中止并且上传流是否已结束。然后通过使用 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 上调用 GridFSBucket 的 delete() 方法,以消除冗余块。此步骤纯粹是可选的,并且出于数据库维护的原因。

于 2020-11-15T20:51:10.170 回答