【问题标题】:NodeJS & Multer: stop uploading file if error occursNodeJS & Multer:如果发生错误,停止上传文件
【发布时间】:2019-09-04 04:59:11
【问题描述】:

你好,我用 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 是中间件,中间件首先执行我希望它阻止它。谢谢!

【问题讨论】:

  • 你想在这里处理什么错误?例如,如果前端的表单包含文件上传和输入字段,并且用户通过仅上传文件而不填写输入来提交表单,那么这种情况下代码是否应该返回错误响应?或者您是否正在尝试处理文件上传本身的错误,例如文件大小超过最大限制或指定文件类型以外的文件类型?
  • 我的意思是第一种情况,当用户填写文件输入但没有填写其他输入时(但如果您对第二种情况有线索,我会很高兴听到它

标签: javascript node.js file-upload upload multer


【解决方案1】:
 app.post('/upload',[
  multer({
    dest    : './uploads/',
    onError : function(err, next) {
      console.log('error', err);
      next(err);
    }
  }),
  function(req, res) {
    res.status(204).end();
  }
]);

//查看 multer docs https://github.com/expressjs/multer#error-handling 中的此链接

【讨论】:

  • 只有在multer内部发生任何错误时才会调用这个errorHander,所以你可以在multer中间件之后编写一个中间件
  • 是的,但是如果您阅读了我的问题,我提到我想要 multer 的错误处理程序,例如当表单没有正确填写时
【解决方案2】:

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

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

为了使用第二步,您可以使用这样的函数

 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 它负责检查一个值是否存在,你可以传递任何你想要的,如果你将输入以及保存的文件传递给它,它将检查它们是否存在,如果不是,它将返回一个false
猜你喜欢
  • 2023-03-09
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 2018-05-27
  • 2016-03-06
  • 1970-01-01
  • 2016-04-22
相关资源
最近更新 更多