Express req.body is empty
Asked Answered
F

6

8

I've tried many StackOverflow answers, and this method normally works using body-parser, however I've been having issues with getting any output from req.body with either AJAX or form data.

In server.js:

app.use(helmet()); // Helmet middleware
app.use('/assets', express.static('resources/web/assets')); // Makes /assets public
app.use(require('./resources/modules/session.js')); // Custom session middleware
app.set('view engine', 'ejs'); // Sets EJS to the view engine
app.set('views', `${__dirname}/resources/web/pages`); // Sets the views folder
app.use(cookieParser()); // cookie-parser middleware
app.use(bodyParser.urlencoded({ extended: true })); // body-parser's middleware to handle encoded data
app.use(bodyParser.json()); // body-parser's middleware to handle JSON
app.use(fileUpload({ limits: { fileSize: 100 * 1024 * 1024 } })); // express-fileupload middleware (bushboy wrapper)
app.use('/api', require('./resources/routes/api.js')); // External API router
// ...
app.post('/login', (req, res) => {
    console.log(req.body);
    res.render('login', {
        config,
        page: {
            name: 'Login'
        },
        error: ''
    });
    res.end();
});

My login.ejs code:

            <form method="POST">
                <div class="input-group">
                    <i class="las la-user"></i>
                    <input placeholder="Username" name="username" type="text" required>
                </div>
                <div class="input-group">
                    <i class="las la-lock"></i>
                    <input placeholder="Password" name="password" type="password" required>
                </div>
                <button type="submit">
                    <i class="las la-paper-plane"></i> Login
                </button>
            </form>

No matter what I try, I always get an empty {} in the console with no avail. I've tried debugging; I need a fresh pair of eyes to see what I've done wrong. Here's the form data: Form Data And I've tried using jQuery's AJAX ($.get) too:

$.post('', {username:'test', password:'test'})
.fail(console.error)
.done(() => console.log('Success'));

enter image description here

Edit: After trying multer's app.use(require('multer')().array()); and app.use(require('multer')().none()); middleware, I'm still at the same old issue, except with multer req.body is now undefined instead of {}. This is due to the data being sent as application/x-www-form-urlencoded instead of what I previously thought was application/form-data. As that is the case, the body-parser middleware method should work. If contributing, please do not contribute an answer relating to parsing application/form-data!

Edit 2: For those asking for the session.js code, here it is:

const enmap = require('enmap'),
      sessions = new enmap('sessions');

module.exports = (req, res, next) => {
    if (!req.cookies) next();
    const { cookies: { session: sessionID } } = req;
    if (sessionID) {
        const session = sessions.get(sessionID);
        if (session) {
            req.session = session;
        } else {
            req.session = undefined;
        };
    } else {
        req.session = undefined;
    };
    next();
};
Farmhand answered 29/6, 2020 at 8:41 Comment(6)
Normally, this should work. I am assuming you would have already done the next given steps but still would like to put those: 1. Is the request header (content type) properly being send - Check network tab? 2. Try using javascript fetch instead of jquery's post 3. and lastly, try hitting the request from API client like Postman to see if the behaviour is same. Might help you to narrow down the issue further.Gossipy
I've checked in network tab and tried with Insomnia.Farmhand
I've run your code and it works for me. Would you please post code of ./resources/modules/session.js?Durazzo
Even I have tried the same code pasted here and tested using postman, Ajax and jQuery as well. And it's working fine.Monorail
Really? The only thing in there is some blank stuff. I'll attach them in the post.Farmhand
The issue should be in one of the previous middlewares, try putting up your route, one line after another, you'll end up identifying the guilty one!Japeth
I
18

For the specific case you're talking about, you usually need only 'body-parser' module to be able to access the form input fields. The minimum example that I advice you to build above it is the following:

var express = require('express');
var bodyParser = require('body-parser');

var app = express();
app.use(bodyParser.urlencoded({extended : true}));
app.use(bodyParser.json());
app.get('/login', (req, res) => { /* ... */ });
app.post('/login', (req, res) => {
    console.log(req.body);
    // ...
});
  
app.listen(3000);

So my advice is to narrow on the cause of the problem by removing any other middleware except for the bodyParser. Try to comment them one-by-one and then you will be able to find the guilty!

Also note that no need to bother yourself trying to make it work with Ajax as it will make no difference. Keep it simple and just try the normal browser submission.

When you found the problematic middleware, debug it. If it's made by you, make sure that you don't make any changes to the req.body. If it a thirdparty middleware, so please consult their installation steps very carefully and I'm happy for further explanation and support

Edit: Some other hints

  • Make sure that the request is being submitted with the header Content-Type: application/x-www-form-urlencoded
  • Check if there any CORS problems
  • File upload middleware to be on a separate path just like the assets
Italicize answered 7/7, 2020 at 12:36 Comment(3)
Thanks - I found out that it was some dodgy session code as many of you pointed out!Farmhand
@Farmhand Glad to hear that! Please mark this answer as the solution if you found it useful.Italicize
when to use application/x-www-form-urlencoded vs application/json as shown here: https://stackoverflow.com/a/29823632 ?Toronto
H
2

Sometimes the main point this doesn't work is - when your data passed in the body is in text format, or as in my case in the headers I had 'Content-Type': 'application/x-www-form-urlencoded', but your req.body is expecting JSON data - so please make sure to double-check the 'Content-Type':'application/json' is set on the request headers.

Hypnotist answered 5/10, 2022 at 7:53 Comment(0)
S
1

Removing enctype="multipart/form-data" from the form elements works for me, also after registering these middlewares:

app.use(express.json());
app.use(express.urlencoded({ extended: true })); 
Stanleigh answered 17/9, 2022 at 17:32 Comment(0)
T
0

You need to use other module to deal with multipart/form-data https://github.com/pillarjs/multiparty

app.post('/login', function (req, res) {
  const form = new multiparty.Form();
  form.parse(req, function(err, fields, files) {
    console.log(fields);
  });
})
Trujillo answered 29/6, 2020 at 8:48 Comment(1)
I think you mean multipart/form-data instead of form/data...Farmhand
M
-1

Please use body parser to get the input from the form

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended : true}));
app.use(bodyParser.json());

app.post('/anyRoute', (req, res) => {
    console.log(req.body); //your input value
});
  
app.listen(3000);
Materialize answered 8/7, 2020 at 2:17 Comment(0)
H
-1

I had this same error and what fixed it was by removing enctype="multipart/form-data" from the form element. If you are not sending a file alongside the form with the enctype attribute, then you get such errors

Hajj answered 23/7, 2021 at 11:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.