Reputation: 376
So, I am working on this express app in which all routes have limited body size, except if you are admin, since admin needs unlimited body size for several routes. I have limitBodySize middleware and I am using it like this: app.use(middleware.limitBodySize)
But in the end my body is not parsed and everything is undefined.
limitBodySize: (req, res, next) => {
let admin = true; // removed extra steps for simplicity
if (admin) {
bodyParser.urlencoded({ extended: false })(req, res, () => {
console.log(req.body) // logs undefined
bodyParser.json()(req, res, () => {
console.log(req.body) // logs undefined
next(); // in next route, console.log(req.body) logs undefined
});
});
} else {
bodyParser.urlencoded({ extended: false, limit: '1kb' })(req, res, () => {
bodyParser.json({ limit: '1kb' })(req, res, () => {
next();
});
});
}
}
How can I solve this, with only one middleware, not by passing bodyParser middlewares to every route or router separetly.
Upvotes: 0
Views: 1289
Reputation: 51886
First of all, you should generate the bodyParser
middleware outside your custom conditional middleware since it's meant to be reusable.
You're also not checking for errors; it's possible that your bodyParser
middleware is providing an error to the anonymous callbacks you've passed as the next
parameter to them, so handle the errors properly. One of the simplest ways to do this is to promisify each of the middleware using the util
module since you're already chaining them anyway.
My suspicion is that your request body might be JSON, and the urlencoded
middleware is attempting to parse it unsuccessfully. At this point, bodyParser
has consumed the body stream, so the json
middleware will probably fail as well. Since you're ignoring both errors, you won't know for sure what the next fix is until you try this:
const { promisify } = require('util')
const json = promisify(bodyParser.json())
const limitedJson = promisify(bodyParser.json({ limit: '1kb' }))
const urlencoded = promisify(bodyParser.urlencoded({ extended: false }))
const limitedUrlencoded = promisify(bodyParser.urlencoded({ extended: false, limit: '1kb' }))
...
limitBodySize: (req, res, next) => {
...
if (admin) {
urlencoded(req, res).then(
() => json(req, res)
).then(
() => next(),
next
)
} else {
limitedUrlencoded(req, res).then(
() => limitedJson(req, res)
).then(
() => next(),
next
)
}
}
This will pass any errors to the express framework using the onRejected
parameter of .then()
Using ECMAScript 2017's async
and await
syntax, you can make it a little easier to read:
limitBodySize: async (req, res, next) => {
...
try {
if (admin) {
await urlencoded(req, res)
await json(req, res)
} else {
await limitedUrlencoded(req, res)
await limitedJson(req, res)
}
next()
} catch (error) {
// if error occurs here, you probably need to figure out what your next issue is
next(error)
}
}
Upvotes: 1