44

I'm making a simple file upload system with 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);
    });
});

This all works fine and the file gets uploaded. The only thing that is not working is the limit on the max size. I made it so that onfileupload start the size of the file gets checked and if its to big it will return false. But the file still just gets uploaded.

It seems that onFileUploadStart isn't doing anything at all. I tried to console.log something in it, but nothing.

What am I doing wrong? How can I limit the file size when uploading with multer?

nbro
  • 15,395
  • 32
  • 113
  • 196
Merijn de Klerk
  • 953
  • 2
  • 11
  • 21
  • Where have you seen that you need to return `false` if `req.files.file.length > maxSize` in the handler of the even `onFileUploadStart`? – nbro Jan 09 '16 at 18:57
  • A tutorial I was following. But I assume u say this is not the right way to stop the upload? – Merijn de Klerk Jan 09 '16 at 19:01
  • Can you `console.log` (before the if statement) the file in that same handler? What do you see? – nbro Jan 09 '16 at 19:08
  • 1
    Apparently maybe you should be using `fileFilter` instead of handling the even `onFileUploadStart` (where apparently the file size is not known yet or is 0...) by the way...Check here on how maybe you should be limiting the file sizes: https://github.com/expressjs/multer/issues/186 If you solve your problem, I encourage you to answer to your own question ;) – nbro Jan 09 '16 at 19:13
  • 1
    There's here also another example of limiting the file size (among other things): https://github.com/expressjs/multer/issues/120: you need basically to specify the file size to a `limits` object that you pass as the property of the object that you pass to `multer`, i.e. something like this `var upload = multer({ storage : storage, limits: {fileSize: maxSize } }).single('bestand');`... – nbro Jan 09 '16 at 19:27

3 Answers3

80

There is no onFileUploadStart with the new multer API. If you want to limit the file size, you should instead add limits: { fileSize: maxSize } to the object passed to multer():

var upload = multer({
  storage: storage,
  limits: { fileSize: maxSize }
}).single('bestand');
mscdex
  • 104,356
  • 15
  • 192
  • 153
14

I think it is you are looking. Have a great day.

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)
    }
}
Joel Peltonen
  • 13,025
  • 6
  • 64
  • 100
Md Saif Uddin
  • 179
  • 2
  • 8
5

For anyone who uses Multer with Ts.ED. When I tried to upload a too large file (no matter what extension it had), I ended up with the following error showing up:

Cannot read properties of undefined (reading 'replace')

I did use the following code to fix this:

@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);
    }
  }
})

Now it works.

mszan
  • 517
  • 5
  • 18