NodeJS和Multer:如果发生错误,停止上传文件

6

你好,我正在使用Node和Multer创建文件上传功能,它可以正常工作,但问题在于如果出现错误(比如用户没有填写其他字段),它仍然会上传文件,而我不希望这样做

我真的不知道该怎么办,因为这是我第一次尝试,希望有经验的人可以帮忙。以下是我的代码:

const storage = multer.diskStorage({

  destination: (req, file, callback) => {
    const userPath = path.join(imgStoragePath, req.userId);
    fs.mkdir(
      userPath,
      () => callback(null, userPath)
    )
  },

  filename: (req, file, callback) => {
    const filenameParts = file.originalname.split('.');
    const ext = filenameParts.pop();
    const basename = filenameParts.join('.');
    const additionalPath = Date.now() + '' + uuid() + '' +             
Math.floor(Math.random() * (2000 - 500)) + 500;
    callback(null, basename + '-' + additionalPath + '.' + ext);
  }

})

const upload = multer({
  storage,
  limits: '1mb'
})


   router.post('/', upload.single('image'), async (req, res) => {
  //code
})

如果出现错误,应该返回错误信息并将其发送到服务器,并停止代码执行而不进行任何操作,它确实能够做到这一点,但还会上传文件。我知道这将发生,因为upload是中间件,中间件首先执行,我希望它可以防止这种情况发生。谢谢!

你在这里想要处理哪些错误?例如,如果前端表单中包含一个文件上传和一个输入字段,并且用户仅上传文件而没有填写输入,则代码应该在这种情况下返回错误响应吗?或者你是想要处理文件上传本身的错误,比如文件大小超过最大限制或文件类型不符合指定的类型? - Jude Fernandes
我指的是第一种情况,即用户填写了文件输入但未填写其他输入(如果您知道第二种情况,我很乐意听取建议)。 - ilia1
2个回答

3

好的,所以 multer 并不会负责验证您的表单输入,它的唯一目的是让您将文件上传到后端。现在进入您要解决的问题

  • 您可以在前端使用 HTML 验证来确保用户在提交表单之前填写所有required字段
  • 您可以进行后端检查,以确保填写了所有required字段

为了使用第2步,您可以使用以下函数:

 export const setRequired = (...args: any): boolean => {
   let isValid = true;
   _.forEach(args, value => {
     if (isUndefined(value)) isValid = false;
   });
   return isValid;
 };

 const isValid: any = setRequired(file, first_name, last_name);

该函数使用TypeScript和Lodash,检查指定的所有参数是否存在。因此,在执行后端操作之前,请将所需字段传递给该函数,它将返回一个布尔值,通知您是否已从前端接收到所有必需的字段。

关于与Multer有关的第二部分文件大小和文件类型错误,您可以尝试类似以下内容的方法:

 const storage = multer.diskStorage({
 destination(req, file, cb) {
   cb(null, path.join(__dirname, `path_to_folder`));
 },
 filename(req, file, cb) {
   const ext = path.extname(file.originalname).toLowerCase();
   const file_name = uuidv4() + "_" + ext;
   cb(null, file_name);
 },
});

const upload = multer({
 storage,
 limits: { fileSize: 2000000 }, // In bytes: 2000000 bytes = 2 MB
 fileFilter(req, file, cb) {
   const ext = path.extname(file.originalname).toLowerCase();
   if (ext !== ".png" && ext !== ".jpg" && ext !== ".jpeg") {
     cb(new Error("Error: Unacceptable file format"), false);
   } else {
     cb(null, true);
   }
 },
}).any();

  router.post("/", (req, res) => {
    upload(req, res, async err => {
      if (err) {
        console.error(err);
        // An unknown error occurred when uploading.
        // the err object will contain the reason for the multer error
      } 

      if (req.files && req.files[0]) {
        // file has been saved 
         console.log(req.files[0].filename);
      }

    });
  },
);

const setRequired 负责仅文件还是每个输入? - ilia1
@ilia1 负责检查值是否存在,您可以传递任何想要的内容,如果您将输入以及保存的文件一起传递,它将检查这些是否存在,如果不存在,则返回 false - Jude Fernandes

0
 app.post('/upload',[
  multer({
    dest    : './uploads/',
    onError : function(err, next) {
      console.log('error', err);
      next(err);
    }
  }),
  function(req, res) {
    res.status(204).end();
  }
]);

//从 multer 文档中查看此链接 https://github.com/expressjs/multer#error-handling


如果在 multer 中发生任何错误,就会调用此 errorHandler,因此您可以编写一个在 multer 中间件后面的中间件。 - vishnu prasath
是的,但如果您读了我的问题,我提到我想要 multer 的错误处理程序,例如当表单未正确填写时。 - ilia1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接