无法在node.js中使用formidable处理错误

问题描述 投票:0回答:1

我正在使用强大的 Node.js 将文件上传到我的 Express 服务器。

我希望能够处理一些错误,例如未选择文件、文件大小超出限制、文件类型检查等,并且能够根据结果向客户端返回特定错误.

但我似乎找不到正确的好方法来做到这一点?

我正在尝试在 form.parse() 中执行此操作,但我在这里遇到问题,因为如果文件超出文件限制,它会停止处理文件?这意味着我无法进行任何类型的检查,因为 file.uploaded 中没有数据?

这是我的代码:

app.post('/putdata', async (req, res, error) => {

    let fileUploaded = '';
    var form = new formidable.IncomingForm({

        //* Set up incoming data requirments
        maxFileSize: 1 * 1024 * 1024,
        minFileSize: 1,

    });

    console.log('Max file size allowed : ' + form.options.minFileSize);
    console.log('Min file size allowed : ' + form.options.maxFileSize);

    const uploaded = await new Promise((resolve,reject) => {

    form.parse(req, function (err, fields, files) {

    
        //* Handle no file uploaded
        if(!files.uploaded) {
            console.log('file not selected.')
            res.status(400).send('No file recieved for upload');
            return;
        } 

        if (err) {
            console.log('error : ' + err)
            return;
        }

        fileUploaded = 'complete';
        resolve(true);
    });

    });
    console.log(fileUploaded);

});

我在这里做错了什么?

感谢您的任何帮助\建议。

javascript node.js formidable
1个回答
0
投票

我在您的代码中发现以下关键问题:

  • 错误处理顺序:在处理 err 之前检查 files.uploaded 可能会错过关键错误,例如文件大小限制。
  • Promise 管理:未解决或拒绝 Promise 的错误,导致潜在的请求挂起。
  • 文件类型验证:不验证可接受的文件类型。

改进的解决方案:

  • 使用带有适当错误处理的 Promise:确保捕获所有可能的错误,并适当地允许或拒绝 Promise。
  • 检查文件类型:检查上传文件的 MIME 类型,以仅允许某些类型。
  • 正确发送响应:确保每个执行路径都发送响应,以防止请求挂起。

修改后的代码示例:

app.post('/putdata', async (req, res) => {
   const form = new formidable.IncomingForm({
      maxFileSize: 1 * 1024 * 1024, // 1 MB
      keepExtensions: true,
   });

   const allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf'];

   const parseForm = () => new Promise((resolve, reject) => {
      form.parse(req, (err, fields, files) => {
         if (err) {
            if (err.code === 'LIMIT_FILE_SIZE') {
               return reject({status: 413, message: 'File size exceeds 1MB limit.'});
            }
            return reject({status: 400, message: err.message});
         }

         const uploadedFile = files.uploaded;
         if (!uploadedFile) {
            return reject({status: 400, message: 'No file received for upload.'});
         }

         if (!allowedMimeTypes.includes(uploadedFile.mimetype)) {
            return reject({status: 400, message: 'Invalid file type uploaded.'});
         }

         resolve({fields, files});
      });

      form.on('error', (err) => {
         console.error('Formidable error:', err);
      });
   });

   try {
      const {files} = await parseForm();
      console.log('File uploaded:', files.uploaded);
      res.status(200).json({message: 'File uploaded successfully.', file: files.uploaded});
   } catch (error) {
      console.error('Upload error:', error);
      res.status(error.status || 500).json({error: error.message || 'Internal Server Error'});
   }
});
© www.soinside.com 2019 - 2024. All rights reserved.