Home > Software engineering >  With node/express/Multer, how do you "first" check a parameter?
With node/express/Multer, how do you "first" check a parameter?

Time:09-27

I use multer exactly like this,

const specialExample = multer({ .. blah blah })
app.post(
    '/specialPath',
    specialExample.single('handled_by_multer'),
    await function (req, res) {
        fs.renameSync(.. move the file, etc
        // send a reply
        res.set('Content-Type', 'text/plain')
        res.status(200).send(`ok`)
    })

So note that things happen in this order:

app.post(
    '/specialPath',
// EXPRESS KNOWS TO GO THIS WAY
    specialExample.single('handled_by_multer'),
// MULTER LITERALLY IS GETTING THE FILE
// MULTER HAS COMPLETELY GOT AND SAVED THE FILE
    await function (req, res) {
// THIS FUNCTION NOW BEGINS RUNNING
        ... etc

That's all perfectly fine.

Now, imagine I want to look at some parameter.

In some cases I DO NOT want to get the file.

const specialExample = multer({ .. blah blah })
app.post(
    '/specialPath',
    specialExample.single('handled_by_multer'),
    await function (req, res) {
        const meta = req.body.meta
        if (meta !== "wth") {
           .. we actually DON'T want the  file
           .. delete the file
           .. send a 401 and return
        }
        fs.renameSync(.. move the file, etc
        // send a reply
        res.set('Content-Type', 'text/plain')
        res.status(200).send(`ok`)
    })

Note that that works fine, BUT, we are wastefully getting/saving the file (and only then deleting it).

Is there a way to do something more like this .......

app.post(
    '/specialPath',

    await function (req, res) {
        .. if I happen to want to, only then: {
            specialExample.single('handled_by_multer'),
        }
    })

How to?

CodePudding user response:

Since multer is the middleware that's (also) parsing the field data that gets stored in req.body, you can't conditionally call it.

Instead, you can use Multer's fileFilter to ignore the file data if your conditions are met:

const specialExample = multer({
  fileFilter(req, file, cb) {
    const meta = req.body.meta;
    if (meta !== "wth") {
      // reject this file
      return cb(null, false);
    }
    return cb(null, true);
  },
  .. blah blah
});
...
app.post(
    '/specialPath',
    specialExample.single('handled_by_multer'),
    await function (req, res) {
      // also have to check here to make sure the correct response is sent
      const meta = req.body.meta
      if (meta !== "wth") {
        return res.sendStatus(401);
      }
      ...
    }
);    

One possible issue: the field(s) that you depend on to check if the file should be rejects (meta in this example) needs to be placed into the multipart data before the file data, otherwise it won't be populated by the time fileFilter() is called.

  • Related