Search code examples
node.jspostmanform-data

Unable to insert data using form-data in Node


The following is a code sample of login API which is created using Node and mongoDB. username and password are two parameters to parse to login in the login API. But the username and the password only allows by Postman Body, x-www-form-urlencoded , but I want to use form-data. When I insert username via form-data Postman shows

{
    "msg": "Invalid request, Invalid 'username' parameter.",
    "status": "Failed"
}

AuthController.js

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

const multer = require('multer');
const storage = multer.diskStorage({});
const upload = multer({storage: storage});

var VerifyToken = require('./VerifyToken');

var User = require('../user/User');

router.use(bodyParser.urlencoded({ extended: false }));
router.use(bodyParser.json());

/**
 * Configure JWT
 */
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var bcrypt = require('bcryptjs');
var config = require('../config'); // get config file
router.post('/login', function(req, res)
{
  postLogName = req.body.username
  postLogPass = req.body.password

  console.log(postLogName);

  if(!postLogName)
  {
      return res.status(400).send(
      {
          "msg": "Invalid request, Invalid 'username' parameter.",
          "status": "Failed"
      });
  } 
  if(!postLogPass)
  {
      return res.status(400).send(
      {
          "msg": "Invalid request, Invalid 'password' parameter.",
          "status": "Failed"
      });
  }
  console.log(postLogName);

  User.findOne({ username: req.body.username }, function (err, user) {
    if (err) return res.status(500).send('Error on the server.');
    if (!user) return res.status(404).send('No user found.');

    // check if the password is valid
    var passwordIsValid = bcrypt.compareSync(req.body.password, user.password);
    if (!passwordIsValid) return res.status(401).send({ auth: false, token: null });

    // if user is found and password is valid
    // create a token
    var token = jwt.sign({ id: user._id }, config.secret, {
      expiresIn: 86400 // expires in 24 hours
    });

    // return the information including token as JSON
    res.status(200).send({ auth: true, token: token });
  });
});

How can I insert using form-data ?

Edited

When I change to "msg" : req Then I tried using form-data I got the following error.

TypeError: Converting circular structure to JSON
    at JSON.stringify (<anonymous>)
    at stringify (C:\userAPI\node_modules\express\lib\response.js:1119:12)
    at ServerResponse.json (C:\userAPI\node_modules\express\lib\response.js:260:14)
    at ServerResponse.send (C:\userAPI\node_modules\express\lib\response.js:158:21)
    at router.post (C:\userAPI\auth\AuthController.js:32:32)
    at Layer.handle [as handle_request] (C:\userAPI\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\userAPI\node_modules\express\lib\router\route.js:137:13)
    at multerMiddleware (C:\userAPI\node_modules\multer\lib\make-middleware.js:18:41)
    at Layer.handle [as handle_request] (C:\userAPI\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\userAPI\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (C:\userAPI\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (C:\userAPI\node_modules\express\lib\router\layer.js:95:5)
    at C:\userAPI\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (C:\userAPI\node_modules\express\lib\router\index.js:335:12)
    at next (C:\userAPI\node_modules\express\lib\router\index.js:275:10)
    at jsonParser (C:\userAPI\node_modules\body-parser\lib\types\json.js:101:7)

Solution

  • 1) Attach multer when You need it, by Your code I don't see where You're using them:

    const multer = require('multer');
    const storage = multer.diskStorage({});
    const upload = multer({storage: storage});
    


    2) Attach body parsers on general level (in app.js), so remove these lines also:

    var bodyParser = require('body-parser');
    
    router.use(bodyParser.urlencoded({ extended: false }));
    router.use(bodyParser.json());
    


    3) In app.js where You've defined express app attach this:

    const bodyParser = require('body-parser');
    const formidable = require('formidable'); // installation: npm i --save formidable
    const multipartForm = new formidable.IncomingForm();
    
    app.use(bodyParser.urlencoded({extended: false}));
    app.use(bodyParser.json());
    
    
    // let's attach our custom middleware
    // which will check headers for content-type
    // and parse request body and 
    // assign body to request context (req object)
    // and call next to pass request handling
    // to next handlers
    app.use((req, res, next) => {
      if (req.headers['content-type'].indexOf('multipart/form-data') > -1) {
        multipartForm
          .parse(req, (error, body, files) => {
            // same as:
            // req.body = body;
            // req.files = files;
            Object.assign(req, {body, files});
            next();
          });
        return;
      }
      next();
    });
    

    So I've tested following code:

    'use strict';
    
    const express = require('express');
    const app = express();
    
    const bodyParser = require('body-parser');
    const formidable = require('formidable');
    const multipartForm = new formidable.IncomingForm();
    
    app.use(bodyParser.urlencoded());
    app.use(bodyParser.json());
    
    app.use((req, res, next) => {
      if (req.headers['content-type'].indexOf('multipart/form-data') > -1) {
        multipartForm
          .parse(req, (error, body, files) => {
            Object.assign(req, {body, files});
            next();
          });
        return;
      }
      next();
    });
    
    app.post('/data', (req, res) => {
      const body = req.body;
      res.status(200).send({body});
    
    });
    
    app.listen(3000);
    

    it works as expected:

    urlencoded url encode form

    form-data mutipart data form

    p.s. You can read about writing middleware here