无法让 multer filefilter 错误处理工作

Posted

技术标签:

【中文标题】无法让 multer filefilter 错误处理工作【英文标题】:Can't get multer filefilter error handling to work 【发布时间】:2016-05-05 03:42:50 【问题描述】:

我正在玩 Node.js/Multer 中的文件上传。

我得到了存储和限制的工作。但现在我正在玩 filefilter 来简单地拒绝 mimetype 的一些文件,如下所示:

fileFilter: function (req, file, cb) 
 if (file.mimetype !== 'image/png') 
  return cb(null, false, new Error('goes wrong on the mimetype'));
 
 cb(null, true);

当上传一个不是 PNG 的文件时,它不会接受它。 但它也不会触发if(err)

当文件太大时,它确实会产生错误。所以不知何故我也需要在filefilter 上生成一个错误,但我不确定如何猜测new Error 是错误的。

那么,如果文件不正确,我应该如何生成错误?我做错了什么?

完整代码:

var maxSize = 1 * 1000 * 1000;

var storage =   multer.diskStorage(
  destination: function (req, file, callback) 
    callback(null, 'public/upload');
  ,
  filename: function (req, file, callback) 
    callback(null, file.originalname);
  
);


var upload = multer(
   storage : storage,
   limits:  fileSize: maxSize ,
   fileFilter: function (req, file, cb) 
     if (file.mimetype !== 'image/png') 
       return cb(null, false, new Error('I don\'t have a clue!'));
     
     cb(null, true);
   

 ).single('bestand');


router.post('/upload',function(req,res)
    upload(req,res,function(err) 
        if(err) 
              return res.end("some error");
        
    )
)

【问题讨论】:

我正在寻找这个 multer(storage, filteFilter...) 谢谢。 【参考方案1】:

fileFilter 函数可以访问请求对象 (req)。该对象在您的路由器中也可用。

因此在 fileFitler 中您可以添加带有验证错误或验证错误列表的属性(您可以上传许多文件,其中一些可以通过)。 在路由器中检查是否存在有错误的属性。

在过滤器中:

fileFilter: function (req, file, cb) 
 if (file.mimetype !== 'image/png') 
  req.fileValidationError = 'goes wrong on the mimetype';
  return cb(null, false, new Error('goes wrong on the mimetype'));
 
 cb(null, true);

在路由器中:

router.post('/upload',function(req,res)
    upload(req,res,function(err) 
        if(req.fileValidationError) 
              return res.end(req.fileValidationError);
        
    )
)

【讨论】:

如果把exe文件的ext改成png,就可以让multer傻了。 当然。它总是关于你想要什么。有时检查 ext 就足够了,我们不在乎它会发生什么。有时您想检查文件的第一个字节以确定它的真实类型 - 例如,当您需要对该文件执行某些操作时。但是如果文件损坏了怎么办。在这种情况下,您还需要检查完整文件。作为工程师,我们的责任是为每个场景选择最佳工具【参考方案2】:

您可以将错误作为第一个参数传递。

multer(
  fileFilter: function (req, file, cb) 
    if (path.extname(file.originalname) !== '.pdf') 
      return cb(new Error('Only pdfs are allowed'))
    

    cb(null, true)
  
)

【讨论】:

【参考方案3】:

更改fileFilter 并将错误传递给cb 函数:

function fileFilter(req, file, cb)
   if(file.mimetype !== 'image/png')
       return cb(new Error('Something went wrong'), false);
    
    cb(null, true);
;

【讨论】:

我在使用 res.render('fileuploaded') 成功上传时显示 fileuploaded.hbs 模板有没有办法在模板中显示错误,而不仅仅是显示通用浏览器错误页面? 【参考方案4】:

fileFilter 回调应该是:

fileFilter: async (req, file, cb) => 
    if (file.mimetype != 'image/png') 
        cb(new Error('goes wrong on the mimetype!'), false);
    
    cb(null, true);

请求中的错误处理:

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

router.post('/upload', function(req, res) 
    upload(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);
        

    )
)

【讨论】:

以上是关于无法让 multer filefilter 错误处理工作的主要内容,如果未能解决你的问题,请参考以下文章

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

如何在multer中检查文件类型

Multer模块将无法启动

Multer - 无法读取未定义的属性“缓冲区”

Nextjs - multer - TypeError:无法读取未定义的属性“传输编码”

Multer 返回 req.file 未定义