Adam Matan
Adam Matan

Reputation: 136141

Natively access JSON POST payload from Node.js server

Consider the following HTTP POST call to a Node.js server:

curl -H "Content-Type: application/json" \
     -X POST \
     -d '{"jsonKey":"jsonValue"}' \
     'http://localhost:8080?abcd=efgh'

I would like to access both the URL parameters and the JSON payload of the POST request.

Accessing the URL params is pretty straightforward by importing url.parse:

var server = http.createServer(function(req, res) {
        // Parse the params - prints "{ abcd: 'efgh' }"
        var URLParams = url.parse(req.url, true).query;
        console.log(URLParams);

        // How do I access the JSON payload as an object?
}

But how do I access the JSON payload, using native Node.js library (without any npm import)?

What have I tried

Upvotes: 1

Views: 4029

Answers (3)

j3141592653589793238
j3141592653589793238

Reputation: 1894

Just as an addition; if you'd like to create an object from the POST body, I am using the following piece of code:

const body2Obj = chunk => {
  let body = {};
  let string = chunk.toString();
  if (!string.trim()) return body;
  string.split('&').forEach(param => {
    let elements = param.split('=');
    body[elements[0]] = elements[1];
  });
  return body;
};

And then use that as already explained by stdob-- above:

var body = [];
req.on('data', chunk => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body);
  body = body2Obj(body);
  // ...
});

I prefer this solution instead of using an oversized third-party module for just parsing the body of the request (sometimes, people suggest that for some reason). Might be that there's a shorter version of mine. Of course, this works only for url-encoded formatted bodies.

Upvotes: 1

stdob--
stdob--

Reputation: 29172

From documentation:

When receiving a POST or PUT request, the request body might be important to your application. Getting at the body data is a little more involved than accessing request headers. The request object that's passed in to a handler implements the ReadableStream interface. This stream can be listened to or piped elsewhere just like any other stream. We can grab the data right out of the stream by listening to the stream's 'data' and 'end' events.

https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#request-body

var server = http.createServer(function(req, res) {
        // Parse the params - prints "{ abcd: 'efgh' }"
        var URLParams = url.parse(req.url, true).query;
        console.log(URLParams);

        // How do I access the JSON payload as an object?
        var body = [];
        req.on('data', function(chunk) {
            body.push(chunk);
        }).on('end', function() {
            body = Buffer.concat(body).toString();
            if (body) console.log(JSON.parse(body));
            res.end('It Works!!');
        });
});

Upvotes: 3

Explosion Pills
Explosion Pills

Reputation: 191729

req is a stream so how you access it depends on how you want to use it. If you just want to get it as text and parse that as JSON, you can do the following:

let data = "";
req.on("readable", text => data += text);
req.on("end", () => {
  try {
    const json = JSON.parse(data);
  }
  catch (err) {
    console.error("request body was not JSON");
  }
  /* now you can do something with JSON */
}); 

Upvotes: 1

Related Questions