Reading POST data in Node.js Express, Easy Manager Method

modified

Introduction

A common task of many web applications is the ability to submit a form and read the POST data sent back to the server. Node.js with Express offers a fairly simple method for reading form POST data by simply referring to req.body.nameOfField. However, when data is sent via HTTP post from a REST client, instead of an HTML form, the data is read using a streaming approach via req.on(‘data’) and req.on(‘end’).

In this tutorial, we’ll show how to create a simple node.js javascript manager method for reading POST data. Our manager method will be compatible with both HTML form posts and RESTful client posts.

Reading from an HTML Form is Simple

Node.js with Express allows you to specify in your app.js javascript file if you’d like to use the bodyParser to automatically parse out the POST data from a form submission. You would typically indicate this by including the following line:

1
2
3
4
app.configure(function() {
app.use(express.bodyParser());
...
}

With the bodyParser() setting defined, you can read form POST data by simply referring to req.body.nameOfField.

1
2
3
exports.post = function (req, res) {
res.render('index', { txtName: req.body.txtName });
}

The above code will simply output the HTML form field, txtName, in the response to the page.

Reading from a Streamed Post

Things get slightly more complicated when your node.js application requires reading streaming POST data, such as a request from a REST client. In this case, the request’s property “readable” will be set to true and the POST data must be read in chunks in order to collect all content. This is typically done with the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
exports.post = function (req, res) {
var content = '';

req.on('data', function (data) {
// Append data.
content += data;
});

req.on('end', function () {
// Assuming, we're receiving JSON, parse the string into a JSON object to return.
var data = JSON.parse(content);
res.render('index', { txtName: data.txtName });
});
}

In the above code example, we set up an event for the request “data” call. This indicates to start reading POST data from the request. We set up a second event for the request “end” call. This tell us that we’ve finished reading data. We can now use the final content for processing. Note, the above example assumes that we’re receiving JSON data, which needs to be parsed into an object (from the string that we’ve read). You could just as well send plain text, in which case you would return { txtName: content }.

As you can imagine, for every method where you would be receiving POST data in your node.js javascript web application, you would need to include the above code block. We can actually refactor this code into a single manager method, which will help us abstract away the request.on() calls, clean up our code, and make the reading of node.js form POST data more robust.

Reading Form POST Data, the Easy Way

We can optimize the above code and refactor it to use our new node.js manager method for reading POST data, as follows:

1
2
3
4
5
6
exports.post = function (req, res) {
// Read post data submitted via form.
CommonManager.getPostData(req, res, function (data) {
res.render('index', { txtName: data.txtName });
});
};

In the above code, we’re no longer using req.on(). We’re simply calling our manager method, which takes care of deciding whether to use req.on() or simply processing req.body (as shown in the first example above). The getPostData() method returns the content to us, whether posted from a form or streamed from a REST client. We can then process the content as we need (such as parsing to JSON, etc).

The GetPostData Helper Method

The getPostData method, which takes care of reading the node.js form POST data, is defined as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
CommonManager = {
getPostData: function (req, res, callback) {
// Check if this is a form post or a stream post via REST client.
if (req.readable) {
// REST post.
var content = '';

req.on('data', function (data) {
if (content.length > 1e6) {
// Flood attack or faulty client, nuke request.
res.json({ error: 'Request entity too large.' }, 413);
}

// Append data.
content += data;
});

req.on('end', function () {
// Return the posted data.
callback(content);
});
}
else {
// Form post.
callback(req.body);
}
}
}

In the above code, we first check if the req.readable parameter is set to true. If it is, we need to read the streamed POST data and concatenate the result. During this streaming, we can also make additional checks, such as protecting against large post data (ie., flood attacks), or perhaps logging, etc. If req.readable is false, we’re reading a standard HTML form post. In this case, we’ll simply return the req.body content.

In both scenarios, we return the result in a callback method, which follows the traditional non-blocking IO style of node.js javascript web applications.

Combining the Two Styles of POST Data

We can combine the original two code examples (form POST data and streaming POST data) into a similar code block with our new getPostData() method.

Reading POST Data From a Form

1
2
3
CommonManager.getPostData(req, res, function (data) {
res.render('index', { txtName: data.txtName });
});

Reading POST Data From a REST Client

1
2
3
4
CommonManager.getPostData(req, res, function (data) {
data = JSON.parse(data);
res.render('index', { txtName: data.txtName });
});

Notice, how the above two requests both process the POST data in a similar fashion. The HTML form POST calls getPostData() and returns data.txtName. Likewise, the REST client POST processes calls getPostData() in the same way. In this example, we assume that we’re receiving JSON data from the REST client, in which case we call JSON.parse() on the result.

npm install easypost

The above technique for reading form POST data has been packaged into the node.js module EasyPost, available via npm.

Read POST data in node.js from a form submission or REST client

You can install it by using:

1
npm install easypost

Once installed, simply call:

1
2
3
4
5
var easypost = require('easypost');

easypost.get(req, res, function (data) {
res.render('index', { txtName: data.txtName });
});

See It In Action

You can view an example of the above code running. The form POST is displayed on the page.

You can also trigger the streamed request by POSTing valid JSON for txtName via a REST client to http://easypost.herokuapp.com/rest. For example, use the following format for the data in the request: {“txtName”: “My Name”}

The output will be the newly rendered HTML page.

Download @ GitHub

You can download the project source code on GitHub by visiting the project home page.

About the Author

This article was written by Kory Becker, software developer and architect, skilled in a range of technologies, including web application development, machine learning, artificial intelligence, and data science.

Share