How to disable Express BodyParser for file uploads (Node.js)
If you need to use the functionality provided by express.bodyParser
but you want to disable it for multipart/form-data, the trick is to not use express.bodyParser directly
. express.bodyParser
is a convenience method that wraps three other methods: express.json
, express.urlencoded
, and express.multipart
.
So instead of saying
app.use(express.bodyParser())
you just need to say
app.use(express.json()) .use(express.urlencoded())
This gives you all the benefits of the bodyparser for most data while allowing you to handle formdata uploads independently.
Edit: json
and urlencoded
are now no longer bundled with Express. They are provided by the separate body-parser module and you now use them as follows:
bodyParser = require("body-parser")app.use(bodyParser.json()) .use(bodyParser.urlencoded())
If the need for body parsing depends only on the route itself, the simplest thing is to use bodyParser
as a route middleware function on only the routes that need it rather than using it app-wide:
var express=require('express');var app=express.createServer();app.post('/body', express.bodyParser(), function(req, res) { res.send(typeof(req.body), {'Content-Type': 'text/plain'});});app.post('/nobody', function(req, res) { res.send(typeof(req.body), {'Content-Type': 'text/plain'});});app.listen(2484);
When you type app.use(express.bodyParser())
, almost each request will go through bodyParser
functions (which one will be executed depends on Content-Type
header).
By default, there are 3 headers supported (AFAIR). You could see sources to be sure. You can (re)define handlers for Content-Type
s with something like this:
var express = require('express');var bodyParser = express.bodyParser;// redefine handler for Content-Type: multipart/form-databodyParser.parse('multipart/form-data') = function(req, options, next) { // parse request body your way; example of such action: // https://github.com/senchalabs/connect/blob/master/lib/middleware/multipart.js // for your needs it will probably be this: next();}
upd.
Things have changed in Express 3, so I'm sharing updated code from working project (should be app.use
ed before express.bodyParser()
):
var connectUtils = require('express/node_modules/connect/lib/utils');/** * Parses body and puts it to `request.rawBody`. * @param {Array|String} contentTypes Value(s) of Content-Type header for which parser will be applied. * @return {Function} Express Middleware */module.exports = function(contentTypes) { contentTypes = Array.isArray(contentTypes) ? contentTypes : [contentTypes]; return function (req, res, next) { if (req._body) return next(); req.body = req.body || {}; if (!connectUtils.hasBody(req)) return next(); if (-1 === contentTypes.indexOf(req.header('content-type'))) return next(); req.setEncoding('utf8'); // Reconsider this line! req._body = true; // Mark as parsed for other body parsers. req.rawBody = ''; req.on('data', function (chunk) { req.rawBody += chunk; }); req.on('end', next); };};
And some pseudo-code, regarding original question:
function disableParserForContentType(req, res, next) { if (req.contentType in options.contentTypes) { req._body = true; next(); }}