当我在multer中使用文件过滤器时如何捕获错误?

时间:2017-12-06 11:46:42

标签: node.js file multer filefilter

我已经搜索但我找不到确切的解决方案..当我上传图片时,它应该只允许jpg,jpeg,gif,png ..如果任何其他文件它应该在UI中显示消息。我使用了以下代码

var upload = multer({ storage: storage,
 fileFilter: function (req, file, cb) {
        var ext = path.extname(file.originalname);
        if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
             return cb(new Error('Wrong extension type'));
            // if(Error){
            //     console.log("error file type")
            // }

        }
        cb(null, true)
    }

});

如果我尝试上传pic而不是jpeg,jpg,png,git它显示错误..但是如何在我的应用程序页面中显示为消息

Error: Wrong extension type
    at fileFilter (D:\Vishnu\octopus new\app\routes.js:912:24)
    at wrappedFileFilter (D:\Vishnu\octopus new\node_modules\multer\index.js:44:7)
    at Busboy.<anonymous> (D:\Vishnu\octopus new\node_modules\multer\lib\make-middleware.js:114:7)
    at emitMany (events.js:127:13)
    at Busboy.emit (events.js:201:7)
    at Busboy.emit (D:\Vishnu\octopus new\node_modules\busboy\lib\main.js:38:33)
    at PartStream.<anonymous> (D:\Vishnu\octopus new\node_modules\busboy\lib\types\multipart.js:213:13)
    at emitOne (events.js:96:13)
    at PartStream.emit (events.js:188:7)
    at HeaderParser.<anonymous> (D:\Vishnu\octopus new\node_modules\dicer\lib\Dicer.js:51:16)
    at emitOne (events.js:96:13)
    at HeaderParser.emit (events.js:188:7)
    at HeaderParser._finish (D:\Vishnu\octopus new\node_modules\dicer\lib\HeaderParser.js:68:8)
    at SBMH.<anonymous> (D:\Vishnu\octopus new\node_modules\dicer\lib\HeaderParser.js:40:12)
    at emitMany (events.js:127:13)
    at SBMH.emit (events.js:201:7)

请在这个问题上帮助我..在此先感谢

4 个答案:

答案 0 :(得分:3)

我现在也一直在努力解决这个问题。我以为我找到了一个解决方案,但结果却不适合我,但经过足够的修修补补,今晚我找到了一个对我有用的答案。我希望这有帮助。 我在寻找答案时实际上发现了这个问题

所以我在你的例子中创建了 req.fileValidationError ,因为:

var upload = multer({ 
     fileFilter: function (req, file, cb) {
          let ext = path.extname(file.originalname);
          if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
               req.fileValidationError = "Forbidden extension";
               return cb(null, false, req.fileValidationError);
         }
         cb(null, true);
     }
});

然后在您的路线中,您想要使用if语句检查 req.fileValidationError 。如果它存在,那么你知道有一个禁止的扩展名。

假设您在 app 变量下使用express,并且您希望发送单个图像,那么它看起来就像这样:

app.post('/your-upload-route', upload.single("your-input-name-here"), function(req, res) {
     if (req.fileValidationError) {
          // return res.sendFile();
          // or return res.end();
          // or even res.render(); whatever response you want here.
     }
});

我希望这有帮助!如果其他人有不同的方式这样做,我很乐意更新我的答案以及看到其他人的见解。

答案 1 :(得分:1)

fileFilter 回调应该是:

var upload = multer({ 
    storage: storage,
    fileFilter: function (req, file, cb) {
        var ext = path.extname(file.originalname);
        if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
            cb(new Error('Wrong extension type'), false);
        }
        cb(null, true)
    }
});

请求中的错误处理:

  • 使用 MulterError 访问 multer 错误
const multer = require("multer");

router.post('/upload', function(req, res) {
    upload.single('field name')(req, res, function(err) {

        // FILE SIZE ERROR
        if (err instanceof multer.MulterError) {
            return res.end("Max file size 2MB allowed!");
        }

        // INVALID FILE TYPE, message will return from fileFilter callback
        else if (err) {
            return res.end(err.message);
        }

        // FILE NOT SELECTED
        else if (!req.file) {
            return res.end("File is required!");
        }
 
        // SUCCESS
        else {
            console.log("File uploaded successfully!");
            console.log("File response", req.file);
        }

    )}
})

答案 2 :(得分:0)

添加到此答案中,顺便说一下,它就像一个咒语。

如果您想全面了解因MIME类型不接受的文件或未附加文件而导致的错误,则可以执行以下操作:

将FileFilter函数设置为如下所示:

const upload = multer({ storage: //storage declaration here, fileFilter: (req, file, cb) => { if ( !file.mimetype.includes("image/png") && !file.mimetype.includes("image/jpeg") ) { return cb(null, false); } cb(null, true); } });

,然后在您的路线或req,res范围内的任何地方,您可以通过检查通常保存上载文件信息的req.file变量来捕获错误并做出相应的响应:

if (!req.file) { console.log("No file received or invalid file type"); return res.status(400).send({ message: "No file received or invalid file type", success: false }); }

如果没有设置新的req变量来保存ValidationError,则可以在用户未提供有效文件的情况下正常响应用户。

之所以可行,是因为FileFilter可以成功过滤出与您的验证不符的文件,即使在回调中不会引发错误,但它不会引发错误,而是不会继续接受文件。我不完全理解为什么multer中的回调是以这种方式构建的,因为引发错误的方法不会冒泡到您的路由或控制器。

但是,使用上述代码,如果fileFilter能够完成工作,则当您使用if(!req.file){}检查req.file是否存在(或在这种情况下不存在)时,您可以捕获无文件提交和一次验证失败,而没有从fileFilter的回调中引发混乱的错误:)

答案 3 :(得分:0)

在中间件的帮助下处理异常的替代方法

router.post("/v1/user/create",uploadFile,customBadRequestException,customBadFileRequestException)

自定义例外

exports.customBadRequestException = (req,res,next) => {
  if(!req.body || !req.body.data || !req.body.data.length || !req.file || !req.file.filename){
    return res.status(400).send({ message: "Bad request" });
  }
  next();
};

exports.customBadFileRequestException = (req,res,next) => {
  if (! /\.(jpe?g|png|gif|bmp)$/i.test(req.file.filename)) {
    return res.status(400).send({ message: "Please upload only images" });
  } 
  next();
};

Multer 配置

const multer = require("multer");
    var storage = multer.diskStorage({
      destination: (req, file, cb) => {
        cb(null,"/Users/path/Desktop/testFiles");
      },
      filename: (req, file, cb) => {
        cb(null, `${Date.now()}-${file.originalname}`);
      },
    });
    
    var uploadFile = multer({ storage: storage}).single("file");
    module.exports = uploadFile;