58

I'm receiving data on a webhook URL as a POST request. Note that the content type of this request is application/x-www-form-urlencoded.

It's a server-to-server request. And On my Node server, I simply tried to read the received data by using req.body.parameters but resulting values are "undefined"?

So how can I read the data request data? Do I need to parse the data? Do I need to install any npm module? Can you write a code snippet explaining the case?

Sowmay Jain
  • 865
  • 1
  • 10
  • 21
  • first check the request object data its contain your data or not then check params,query,body object.Print the request in console. – Yash Feb 09 '17 at 05:41

6 Answers6

81

If you are using Express.js v4.16+ as Node.js web application framework:

import express from "express";

app.use(bodyParser.json()); // support json encoded bodies
app.use(express.urlencoded({ extended: true })); // support encoded bodies

// With body-parser configured, now create our route. We can grab POST 
// parameters using req.body.variable_name

// POST http://localhost:8080/api/books
// parameters sent with 
app.post('/api/books', function(req, res) {
  var book_id = req.body.id;
  var bookName = req.body.token;
  //Send the response back
  res.send(book_id + ' ' + bookName);
});

For versions of Express.js older than v4.16 you should use the body-parser package:

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

// With body-parser configured, now create our route. We can grab POST 
// parameters using req.body.variable_name

// POST http://localhost:8080/api/books
// parameters sent with 
app.post('/api/books', function(req, res) {
  var book_id = req.body.id;
  var bookName = req.body.token;
  // Send the response back
  res.send(book_id + ' ' + bookName);
});
Samuel Lindblom
  • 812
  • 1
  • 6
  • 22
samith
  • 1,042
  • 8
  • 5
  • Should work, if you need a more detailed answer (very similar to this one) you can see this: https://scotch.io/tutorials/use-expressjs-to-get-url-and-post-parameters – ahong Feb 12 '19 at 05:24
  • 10
    In the newests versions of Node, it no longer needed to add body-parser package. The express by it self can handle it, using app.use(express.urlencoded({ extended: true })) – joao Feb 17 '21 at 16:01
8

The accepted answer uses express and the body-parser middleware for express. But if you just want to parse the payload of an application/x-www-form-urlencoded ContentType sent to your Node http server, then you could accomplish this without the extra bloat of Express.

The key thing you mentioned is the http method is POST. Consequently, with application/x-www-form-urlencoded, the params will not be encoded in the query string. Rather, the payload will be sent in the request body, using the same format as the query string:

param=value&param2=value2 

In order to get the payload in the request body, we can use StringDecoder, which decodes buffer objects into strings in a manner that preserves the encoded multi-byte UTF8 characters. So we can use the on method to bind the 'data' and 'end' event to the request object, adding the characters in our buffer:

const StringDecoder = require('string_decoder').StringDecoder;
const http = require('http');

const httpServer = http.createServer((req, res) => {
  const decoder = new StringDecoder('utf-8');
  let buffer = '';

  req.on('data', (chunk) => {
    buffer += decoder.write(chunk);
  });

  req.on('end', () => {
    buffer += decoder.end();
    res.writeHead(200, 'OK', { 'Content-Type': 'text/plain'});
    res.write('the response:\n\n');
    res.write(buffer + '\n\n');
    res.end('End of message to browser');
  });
};

httpServer.listen(3000, () => console.log('Listening on port 3000') );
Daniel Viglione
  • 8,014
  • 9
  • 67
  • 101
  • 1
    You're reinventing the wheel. `body-parser` is well known, well documented and does the job better than your snippet. It provide various middlewares for parsing and supports the inflation of `gzip` and `deflate` encodings. Downvote – Ahmed Shaqanbi May 20 '22 at 10:56
8

You must tell express to handle urlencoded data, using an specific middleware.

const express = require('express');
const app = express();

app.use(express.urlencoded({
    extended: true
}))

And on your route, you can get the params from the request body:

const myFunc = (req,res) => {
   res.json(req.body);
}
joao
  • 382
  • 4
  • 12
4

If you are creating a NodeJS server without a framework like Express or Restify, then you can use the NodeJS native querystring parser. The content type application/www-form-urlencoded format is the same as the querystring format, so we can reuse that built-in functionality.

Also, if you're not using a framework then you'll need to actually remember to read your body. The request will have the method, URL, and headers but not the body until you tell it to read that data. You can read up about that here: https://nodejs.org/dist/latest/docs/api/http.html

James
  • 3,051
  • 3
  • 29
  • 41
3

Express 4.16+ has implemented their own version of body-parser so you do not need to add the dependency to your project.

app.use(express.urlencoded()); //Parse URL-encoded bodies

Non-deprecated alternative to body-parser in Express.js

rofrol
  • 14,438
  • 7
  • 79
  • 77
0

If you are using restify, it would be similar:

var server = restify.createServer()
server.listen(port, () => console.log(`${server.name} listening ${server.url}`))
server.use(restify.plugins.bodyParser()) // can parse Content-type: 'application/x-www-form-urlencoded'
server.post('/your_url', your_handler_func)
Marshal
  • 4,452
  • 1
  • 23
  • 15