如何使用multer上传文件时限制文件大小?

47

我正在使用multer创建一个简单的文件上传系统:

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);
  },
  onFileUploadStart: function(file, req, res){
    if(req.files.file.length > maxSize) {
      return false;
    }
  }

});

var upload = multer({ storage : storage}).single('bestand');

router.post('/upload',function(req,res){
    upload(req,res,function(err) {
        if(err) {
            return res.end("Error uploading file.");
        }
        console.log(req.file);
        res.redirect(req.baseUrl);
    });
});

所有操作都正常,文件已成功上传,唯一不起作用的是文件大小的限制。我已经设置了在 onfileupload 开始时检查文件大小,如果文件过大,则返回 false。但是文件仍然可以上传。

似乎 onFileUploadStart 根本没有起作用。我试过在里面使用 console.log,但没有任何输出。

我做错了什么?如何使用 multer 限制上传文件的大小呢?


你在哪里看到需要在onFileUploadStart事件的处理程序中返回false,如果req.files.file.length > maxSize - nbro
我正在跟随的教程。但我认为你说这不是停止上传的正确方法? - Merijn de Klerk
你能否在同一个处理程序中的 if 语句之前使用 console.log 输出文件?你看到了什么? - nbro
1
显然,也许你应该使用 fileFilter 而不是处理事件 onFileUploadStart(在那里显然文件大小还不知道或为0...)。顺便说一下,你可以在这里查看如何限制文件大小:https://github.com/expressjs/multer/issues/186。如果你解决了问题,我鼓励你回答自己的问题 ;) - nbro
1
这里还有另一个限制文件大小的示例(以及其他内容):https://github.com/expressjs/multer/issues/120:你基本上需要将文件大小指定为`limits`对象,将其作为传递给`multer`的对象属性传递,例如 var upload = multer({ storage : storage, limits: {fileSize: maxSize } }).single('bestand');... - nbro
3个回答

82

使用新版的multer API,没有 onFileUploadStart 事件。如果您想限制文件大小,则应该将limits: { fileSize: maxSize } 添加到传递给 multer() 方法的参数对象中:

var upload = multer({
  storage: storage,
  limits: { fileSize: maxSize }
}).single('bestand');

9
你应该可以添加一个 Express 错误处理程序并检查 err.code === 'LIMIT_FILE_SIZE' - mscdex
7
@mscdex 我也用了 fileSize。但我不认为它会在超过限制时停止上传。相反,它会上传整个文件,然后检查限制。我有什么遗漏吗? - Jayadratha Mondal
1
如果你能证明的话,我建议你在Github的multer问题跟踪器上提交一个问题。 - mscdex
6
@mscdex 是的,这是一个问题,请尝试上传一个1GB的文件,你就能理解了。我和 LinusU (Multer的维护者)进行了交谈。并且这个问题已经被列出来了,https://github.com/expressjs/multer/issues/344。我正在尝试使用multer v2.0 alpha版本。他说这个问题可能会在v2中得到解决。 - Jayadratha Mondal
2
@JayadrathaMondal 这个问题仍然没有解决。这个问题有任何更新吗?最后一次回复是在三月份,到目前为止我还没有看到他们积极尝试修复这个问题。 - linus_hologram
显示剩余4条评论

16

我认为这就是你在寻找的。 祝你有美好的一天。

const fileFilterMiddleware = (req, file, cb) => {
    const fileSize = parseInt(req.headers["content-length"])

    if ((file.mimetype === "image/png" || file.mimetype === "image/jpg" || file.mimetype === "image/jpeg" || file.mimetype === "application/octet-stream") && fileSize <= 1282810) {
        cb(null, true)
    } else if (file.mimetype === "video/mp4" && fileSize <= 22282810) {
        cb(null, true)
    } else {
        cb(null, false)
    }
}

5

对于任何使用Ts.ED的用户来说,如果您使用Multer上传文件时遇到文件过大(不管它是什么扩展名),则会出现以下错误:

Cannot read properties of undefined (reading 'replace')

我使用了以下代码来解决这个问题:

@Configuration({
  ...
  multer: {
    limits: {
      fieldNameSize: 300,
      fileSize: 1048576, // 10 Mb
    },
    fileFilter: (req, file, callback) => {
      const acceptableExtensions = ['.png', '.jpg'];
      if (!(acceptableExtensions.includes(Path.extname(file.originalname)))) {
        return callback(new Error('...'));
      }

      // added this
      const fileSize = parseInt(req.headers['content-length']);
      if (fileSize > 1048576) {
        return callback(new Error('...'));
      }
      // --


      callback(null, true);
    }
  }
})

现在它可以运行了。


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