How can I easily get access to form data in Express js?
Asked Answered
H

7

97

I have a POST request with very simple and small amount of form data. How can I most easily access it?

Many tutorials/posts etc talk about bodyParser, but this is no longer bundled with Express. Other places (blogs etc) recommend using urlencoded directly, but now this is not available either.

Trying to find accurate information on these frameworks or technologies is doing my head in.

Can someone please tell me the recommended (up to date) way to get POSTed form data in Express?

Hierocracy answered 17/7, 2014 at 10:3 Comment(3)
This should not be downvoted. There really is no simple documentation for how to read a single POST parameter. The accepted solution uses a deprecated package.Tenderfoot
Jeremy I think that the accepted solution is not a deprecated package. The package Mritunjay refers to has a hyphen in its name and I believe is different to the "bodyparser" middleware that is vulnerable. I think it is referred to in some of the blog posts warning about the original "bodyparser". This is why I agree that it should not be downvoted (ie does not show any research effort) because I searched for ages for a solution but the problem is there is so much old and confusing information around it was doing my head in.Hierocracy
Thanks for the clarification; I didn't realize there was a difference between the body-parser and bodyParser packages. That subtlety is part of the reason this question is a proper one.Tenderfoot
F
88

You should install body-parser through npm-install. Now it comes as a separate middleware.

After that add following line in your app.js

var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
// in latest body-parser use like below.
app.use(bodyParser.urlencoded({ extended: true }));

It parses the post request as an object. You will get your variables in req.body.

In your post request handler.

app.post('/post',function(request,response){
   console.log(request.body) //you will get your data in this as object.
})

Edit 1

The answer above was for the question specifically asked, the OP was looking for the bodyParser(deprecated) which was not part of express anymore.

Since the title of the question is very generic and the answer doesn't include all aspects of form-data, I will put @StLia's answer as an edit.

Body-Parser Readme

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:

Ferryboat answered 17/7, 2014 at 10:8 Comment(5)
in express 4, now use : app.use(bodyParser.urlencoded({ extended: true }));Heartache
You need to provide the extended option as there is no default in later versions of body-parserLeroylerwick
Yes, but it won't work with FormData() which contains files.@stlia's answer is a good one.Briar
in express 4.16, body-parser is now build in. you CAN use app.use(express.urlencoded({ extended: true }));Defalcate
Perhaps you can edit the answer to include that this stuff is bundled with express from v4.16+Allowedly
A
40

You can make use of express-formidable module to that. install 'express-formidable' by the following command

npm install express-formidable

the simple example is as follows

const express = require('express');
const formidable = require('express-formidable');
 
var app = express();
 
app.use(formidable());
 
app.post('/upload', (req, res) => {
  //req.fields contains non-file fields 
  //req.files contains files 
  res.send(JSON.stringify(req.fields));
});

Click here for further description

Achates answered 25/9, 2017 at 6:40 Comment(2)
Worked for me as well. Accepted answer didn't work with FormData() with files.Aram
Tried express formiddable. One issue is noted. If we pass a field's value as number, formiddable converts it to string.Ruby
S
27

From the README of body-parser:

This does not handle multipart bodies, due to their complex and typically large nature.

The above is going to work with x-www-form-urlencoded and json but it will NOT work with any multipart. form-data is also multipart with the header multipart/form-data.

In case of form-data, your best solution would be to use express-formidable.

Snowber answered 6/6, 2017 at 14:52 Comment(0)
O
7

As stated in this StackOverflow answer:

Express 4.16+ has implemented their own version of body-parser so you do not need to add the dependency to your project. You can run it natively in express

app.use(express.json()); // Used to parse JSON bodies
app.use(express.urlencoded()); // Parse URL-encoded bodies using query-string library
// or
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies using qs library

See also: query-string vs qs

Olgaolguin answered 23/10, 2021 at 14:56 Comment(0)
B
5

Besides the solutions with formidable, there is another module which I have been using in my recent projects since 2019. The module express-form-data can be easily declared in your server file like:

const express = require('express');
const formData = require('express-form-data');

app.use(formData.parse());

app.post('/image-upload', (req, res) => {
  console.log(req.files);
})

...

In case of image uploading, for instance, req.files will provide all relevant data you need for handling the files such as path, size, filename, etc.

Bystreet answered 30/4, 2020 at 3:0 Comment(0)
E
5

I noticed @HubballiHuli answer was to use a package called express-formidable. You don't need to use this unnecessary package, it provide one (small) file of code. Instead you can do it yourself (now removing the dependency).

Here is the formidableMiddleware file:

'use strict';

const formidable = require('formidable');

function parse(opts, events) {
  return (req, res, next) => {
    if (req.express_formidable && req.express_formidable.parsed) {
      next();
      return;
    }

    const form = new formidable.IncomingForm();
    Object.assign(form, opts);

    let manageOnError = false;
    if (events) {
      events.forEach((e) => {
        manageOnError = manageOnError || e.event === 'error';
        form.on(e.event, (...parameters) => { e.action(req, res, next, ...parameters); });
      });
    }

    if (!manageOnError) {
      form.on('error', (err) => {
        next(err);
      });
    }

    form.parse(req, (err, fields, files) => {
      if (err) {
        next(err);
        return;
      }

      Object.assign(req, { fields, files, express_formidable: { parsed: true } });
      next();
    });
  };
}

module.exports = parse;
exports.parse = parse;

Now on how to use it:

const express = require('express');
const formidableMiddleware = require('./formidableMiddleware.js');

var app = express();

app.use(formidableMiddleware());

app.post('/upload', (req, res) => {
  //req.fields contains non-file fields 
  //req.files contains files 
  res.send(JSON.stringify(req.fields));
});

I wrote an article on unnecessary packages a while ago and why not to use them: https://medium.com/@alexjamesdunlop/unnecessary-packages-b3623219d86

Epirus answered 31/3, 2021 at 1:35 Comment(0)
M
3

If you would like to apply the formidableMiddleware to only one API route and not globally, this is how you would pass the value.

This would be useful if u want to mix between different headers to pass to the API for other API's which you which u do not want the formidableMiddleware API to be applied.

const express = require('express');
const formidable = require('express-formidable');

var app = express();

app.post('/mypath', formidableMiddleware(), (req, res) => {
  // rest of the code
})
Moonwort answered 9/7, 2022 at 4:43 Comment(1)
This worked for me. In my case, I accessed the form data fields with req.fields.Demarcate

© 2022 - 2024 — McMap. All rights reserved.