Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
233 views
in Technique[技术] by (71.8m points)

node.js - Express built-in parser returns empty req.body

This question is addressed ad nauseum on SO, but they all seem to tell people to use body-parser.

I'm trying to use the built-in parser in Express, rather than body-parser, since body-parser was re-added into Express 4.x so now they're the same thing.

However I'm getting an empty req.body with either multipart/form-data or x-www-urlencoded on both the HTML form and from Postman (resulting in "incorrect username or password" from passport, but that's a separate issue):

const express = require('express');
require('dotenv');
const passport = require('passport');
const mongoose = require('mongoose')

const User = require('../models/user');

passport.initialize();
// CHANGE: USE "createStrategy" INSTEAD OF "authenticate"
passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

require('mongoose-type-url');

//connect to database
mongoose.connect(process.env.DATABASE_URL,{
    useNewUrlParser:true, 
    useUnifiedTopology:true,
  useFindAndModify: false,
  useCreateIndex:true
}).then(() => {
    console.log('Connected to Mongo DB');
}).catch(err => {
    console.log('Mongoose error: ',err);
});
 
const app = express();
/* This is where npx express-generator automatically created the 'app.use' 
lines for the input parsers, both for json and urlencoded. 
I haven't touched this, it should be working just fine */
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(require('cookie-parser')());
app.use(require('express-session')({
  secret:"more things in the world",
  resave: false,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
 
app.post('/login', testPostLogin);

// POST /login
async function testPostLogin(req, res, next) {
  const {username, password } = req.body;
  const { user, error } = await User.authenticate()(username, password);
  if(!user && error) {
      return next(error);
  }
  req.login(user, function (err) {
      if(err){
          return next(err);
      }
      req.session.success = `Welcome back, ${username}`;
      /*if they came to the login page from somewhere that called 'isLoggedIn', 
      send them back there after logging in, then remove the hook to do that */
      const redirectUrl = req.session.redirectTo || '/';
      delete req.session.redirectTo;
      res.redirect(redirectUrl);
  });
}

let port = process.env.PORT;
if (port == null || port == "") {
  port = 8080;
}
app.listen(port, () => {
    console.log("server has started, listening on port "+port);
});

Postman curl:

curl --location --request POST 'http://127.0.0.1:8080/login' 
--header 'Cookie: connect.sid=s%3A0aRKbFHVGSiUk-53HCZjuHKqYFAHIV7j.H9SDAJEDwY4rla2K%2BQ7ejiIJCMekMvhyeU8IH1sIh%2BE' 
--form 'username="bob"' 
--form 'password="password"'

Am I missing something stupidly obvious in my setup that is preventing express from parsing the body of the POST request?

UPDATE 2021-01-26 16:04 CST: I tried subbing in body-parser just to see what would happen, and still zilch. So is the issue that the middleware isn't being called on the route? Does that mean there's something wrong in my order of requirements?

question from:https://stackoverflow.com/questions/65908909/express-built-in-parser-returns-empty-req-body

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

if you read body-parser documentation it's not possible, you should use third party module

This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:

busboy and connect-busboy, multiparty and connect-multiparty, formidable, multer

If your form isn't sending any actual multipart information, only text, the express.urlencoded() should be able to parse it if sent with application/x-www-form-urlencoded headers


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...