Node.js (with express & bodyParser): unable to obtain form-data from post request

102,027

Solution 1

In general, an express app needs to specify the appropriate body-parser middleware in order for req.body to contain the body.

[EDITED]

  1. If you required parsing of url-encoded (non-multipart) form data, as well as JSON, try adding:

    // Put this statement near the top of your module
    var bodyParser = require('body-parser');
    
    
    // Put these statements before you define any routes.
    app.use(bodyParser.urlencoded());
    app.use(bodyParser.json());
    

    First, you'll need to add body-parser to the dependencies property of your package.json, and then perform a npm update.

  2. To handle multi-part form data, the bodyParser.urlencoded() body parser will not work. See the suggested modules here for parsing multipart bodies.

Solution 2

To handle multipart/form-data request that support file upload, you need to use multer module. npm link for multer middleware

Solution 3

I followed this https://www.tutorialspoint.com/expressjs/expressjs_form_data.htm

var bodyParser = require('body-parser');
var multer = require('multer');
var forms = multer();

// apply them

app.use(bodyParser.json());
app.use(forms.array()); 
app.use(bodyParser.urlencoded({ extended: true }));

// how to use

router.post('/', function(req, res) {
    console.log(req.body);
    console.log('received the widget request');
});

Solution 4

Make sure to put in this order: bodyParser.json() first. app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true }));

Solution 5

  • For Json: Use body-parser.
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))

(you should Also send Content-Type: application/json in request header)

  • For Normal Form, Or multipart form (form with files), Use body-parser + multer.
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
app.use(multer().array())

(You should NOT send Content-Type: application/json in this case. you should send nothing, or Content-Type: multipart/form-data if you have files in form.

  • in postman you should not send Content-Type: multipart/form-data manually. otherwise you'll get an error (Boundary not found). (it will add this automatically.).)
Share:
102,027

Related videos on Youtube

Jem
Author by

Jem

Updated on July 09, 2022

Comments

  • Jem
    Jem almost 2 years

    I can't seem to recover the form-data of a post request sent to my Node.js server. I've put below the server code and the post request (sent using postman in chrome):

    Post request

    POST /api/login HTTP/1.1
    Host: localhost:8080
    Cache-Control: no-cache
    
    ----WebKitFormBoundaryE19zNvXGzXaLvS5C
    Content-Disposition: form-data; name="userName"
    
    jem
    ----WebKitFormBoundaryE19zNvXGzXaLvS5C
    

    NodeJS server code

    var express    = require('express');        // call express
    var app        = express();                 // define our app using express
    var bodyParser = require('body-parser');
    
    app.use(bodyParser.urlencoded({ extended: true }));
    app.use(bodyParser.json());
    app.use(bodyParser());
    
    app.all('/*', function(req, res, next) {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Headers', 'Content-Type,accept,access_token,X-Requested-With');
        next();
    });
    
    var port = process.env.PORT || 8080;        // set our port
    
    var router = express.Router();              // get an instance of the express Router
    
    router.get('/', function(req, res) {
    
        res.json({ message: 'I am groot!' });   
    });
    
    // Login
    router.route('/login')
    
        .post(function(req, res){
    
            console.log('Auth request recieved');
    
            // Get the user name
            var user = req.body.userName;
    
            var aToken = getToken(user);
    
            res.json({
    
                'token':'a_token'
            });
        });
    
    app.use('/api', router);
    
    app.listen(port);
    

    The login method tries to obtain the req.body.userName, however, req.body is always empty. I've seen other cases on SO describing such behavior but none of the related answers did apply here.

    Thanks for helping out.

    • Jonathan Lonowski
      Jonathan Lonowski over 9 years
      The issue is that the request's body is a multipart message and the body-parser module does not support parsing data in that format. The 2nd paragraph in its README offers suggestions for other modules you can use.
    • Jonathan Lonowski
      Jonathan Lonowski over 9 years
      Or, if the data in the POST request does not require multipart, it can be sent as x-www-form-urlencoded. This is the format that bodyParser.urlencoded() parses.
    • Jem
      Jem over 9 years
      Indeed, thanks for pointing out. My knowledge of HTTP is limited, so didn't knew about form-urlencoded. That way, my node.js can properly handle the post requests from the little angular frontend. Thanks for the help!
  • Jonathan Lonowski
    Jonathan Lonowski over 9 years
    The OP shows body-parser is being used. The module does not, however, support multipart parsing.
  • cybersam
    cybersam over 9 years
    I've edited my answer to include a reference to suggested modules for multipart form parsing. Thanks to @Jonathan for the reference.
  • Jem
    Jem over 9 years
    Thanks for the help. Indeed, I was sending form-data, not knowing the server was able to accept url-encoded data. It works with the latter.
  • Jem
    Jem over 9 years
    Will look at the pro&cons of url-encoded vs. form-data. Thanks again!
  • Camilo Ortegón
    Camilo Ortegón about 6 years
    How to read the body from post before multer process the upload?
  • Neithan Max
    Neithan Max over 5 years
    It'd be beneficial to have an explanation as to why.
  • Aecio Levy
    Aecio Levy over 5 years
    Carles Alcolea, Both are middleware that will be executed in this order. I have not looked the source code, But I would bet that with urlenconded first if the body is a JSON it might send an error back instead of skip and call the next middleware. This might be what the JSON module does, it is not a JSON, skip (call next()) instead of sending an error back and call the next middleware.
  • Neithan Max
    Neithan Max over 5 years
    I meant it as in editing your answer adding a much-needed explanation for anyone who reads it. It's much more educative and clear when we justify our answers. It also helps us make sure we are sure of our answer ;P
  • Geek Guy
    Geek Guy over 4 years
    @CamiloOrtegón did you find the solution to your question in the comment above?
  • Greggory Wiley
    Greggory Wiley almost 3 years
    Same issue for me, need to handle the text data and the upload seperately.
  • Zackattack
    Zackattack about 2 years
    when i console.log(req.body) i get {}