NodeJS req.body is always empty - node.js

My server.js code:
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Origin', '*');
next();
});
const AboutController = require('./controllers/AboutController');
app.use('/about', AboutController);
AboutController.js
router.post('/store', (req, res, next) => {
// GETTING REQUEST DETAILS AND INITIALIZATION
let content = req.body.content;
let company_name = req.body.company_name;
console.log(req.body);
});
module.exports = router;
Problem
req.body always return {} which is empty object and I don't know why!
What I have tried
I have tried to console.log(req) and it returned objects but still the body object is empty!
Client Side Request
I am using Postman form-data to simulate client request.

The reason your Postman request didn't work is because you aren't parsing a form-data type anywhere in your app. The only middleware that you have for parsing is bodyParser.json(), which as it says on the tin, parses JSON. For example, if you wanted to parse x-www-form-urlencoded, you could use bodyParser.urlencoded().
If you want what you currently have to work, you need to send it JSON, not form-data
Regardless, the form-data type is normally used for larger payloads (ex: files)

I found the solution..
I was using Postman and I was using form-data instead of raw and json and it worked fine I don't know why yet!

Related

Postman send strange response for raw JSON post (node js)

I'm trying to do a POST request using raw json.
In the Body tab I have "raw" selected with this body:
{
"name": "book"
}
On the Node js side I'm doing res.send(JSON.stringify(req.body))
router.post('/', (req, res, next) => {
res.send(JSON.stringify(req.body));
}
And in POSTMAN response I receive:
{"{\n\"name\": \"book\"\n}":""}
When expected something like
{"name":"book"}
Have no idea - where could be a reason for it?
You'll need to use the Express JSON body parser, install using
npm install body-parser;
Then:
const bodyParser = require('body-parser');
app.use(bodyParser.json());
Once you do this, the JSON data will be parsed correctly and when you send it back it will render correctly.
Also make sure you have your Content-Type header set to "application/json" in your Postman request (go to "Headers" and add a new "Content-Type" header with value "application/json")
Here's a simple express app that will echo any JSON POST:
const express = require("express");
const port = 3000;
const app = express();
const bodyParser = require('body-parser')
app.use(bodyParser.json());
app.post('/', (req, res, next) => {
console.log("Body: ", req.body);
res.send(JSON.stringify(req.body));
})
app.listen(port);
console.log(`Serving at http://localhost:${port}`);
If you're on Express v4.16.0 onwards, try to add this line before app.listen():
app.use(express.json());
This is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on body-parser.
Looks to me like its not a fault of Postman, but your NodeJS service is applying JSON.stringify twice?
Can you log the response type from the server to console to check whether its already json content or not?
try with hard coded json response and then with dynamic variable
res.json({"name":"book"});

How to retrieve form-data sent from postman in express?

I successfully retrieved data in node when it was x-www-form-urlencoded or raw.
app.use(express.json());
app.use(express.urlencoded());
app.post("/api/posttest", (req, res) => {
console.log(req.body);
res.send("POST data received");
});
But when I use form-data, the req.body is empty and I didn't find my data anywhere else in req. Can this be retrieved with express without additional modules?
I believe you need the express.js middleware 'body-parser' in order to retrieve/see req.body.
Body parser used to be part of express.js but has since been removed.

Add header to all responses after processing but before sending to client

I have two endpoints in a node js app:
app.get('search', myGetController);
app.post('add', myPostController);
For simplicity, let's assume both services have only the following code:
exports.myGetController = function(req, res) {
res.status(404).json({ error: "not found" });
};
I want to have a middleware that is executed after the processing of the controllers, but before they are sent to the browser, so I can add a header based on the body of the response.
// process all responses to add ed25519
app.use(function(req, res, next) {
res.setHeader('CharCount', [How To get Body content]);
next();
});
I have two questions:
First of all, I would like to have all my controllers pass by that middleware after processing.
Second, I would like to access the body content so I can generate a header based on its content.
UPDATE
I have tried the suggested answer someone posted, and it is not working, or I am missing something.
This is what I have (before setting up my routes):
app.use(function(req, res, next) {
const oldResJson = res.json;
res.json = function(body) {
res.setHeader('myToken', generateHeaderBasedOnBody(oldResJson));
oldResJson.call(res, body);
}
next();
});
The response that is being passed to my method is an empty string, even though the response sent by the service is not empty. Am I doing this in the wrong place, or what am I missing?
One solution for this issue would be to override the res.json function like so:
// process all responses to add ed25519
app.use(function(req, res, next) {
const oldResJson = res.json;
res.json = function(body) {
res.setHeader('CharCount', /* Use body here */);
oldResJson.call(res, body);
}
next();
});
By doing this, you don't even need to change your controllers.

ExpressJS: Append header to incoming request object

I'm trying to append additional header to an incoming request, it can't seem to work.
server.get('/', function md1(req, res, next) {
req.setHeader('px-test-header', 1234); // Error - "req.setHeader is not a function"
req.headers['px-test-header'] = 1234; // nothing happens
}, function (req, res, next) {
console.log(req.get('px-test-header')); // always undefined
}, handler);
What am I doing wrong? Is it even possible?
Note - I do not want to modify the request object with additional parameter instead.
setHeader is a function for response type of objects not requests as from the documentation
But if you still want to set the headers in request then you could do something like
app.get('/', function(req,res){
req.headers.abc ='xyz';
console.log(req);
});
req are stored in req.headers so you could add your custom headers here for application middle wares to use later.
You can set header before routing.
Check this code
var router = express.Router();
router.use(function(req, res, next) {
// set the header you wish to append
req.headers('px-test-header', 1234);
next();
});
router.get('/', function(req, res){
console.log(req.headers)
});

Handling text/plain in Express (via connect)?

I am using Express 3, and would like to handle text/plain POSTs.
Express 3 uses connect's bodyParser now (I think the old Express code got moved to connect). The documentation for bodyParser gives some details about how to make it support additional file types. And I found an excellent blog post about how handling text/plain was done in old versions of Express).
Should I explicitly require connect (and let node's require cache the modified version)? Or is connect exposed via express somewhere?
connect.bodyParser does not have a 'parse' key.
How can I make Express (via connect) handle text/plain POSTs?
With bodyParser as dependency, add this to your app.js file.
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.text());
Happy Noding.
https://gist.github.com/3750227
app.use(function(req, res, next){
if (req.is('text/*')) {
req.text = '';
req.setEncoding('utf8');
req.on('data', function(chunk){ req.text += chunk });
req.on('end', next);
} else {
next();
}
});
Will add the text as req.text
In express.js "^4.16..." the following code works fine for me:
// parse an HTML body as a string
app.use(bodyParser.text({ type: 'text/*' }))
The extended piece of the code is below:
// parse an HTML body as a string
app.use(bodyParser.text({ type: 'text/*' }))
// Enable CORS for ExpressJS
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS')
res.header('Access-Control-Allow-Credentials', true)
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Methods, Credentials')
next()
})
// Api url
app.post('/api/myApi', (req, res) => {
const bodyJson = JSON.parse(req.body)
// do something
}
I would just make a module similar to the json.js middleware module and just don't bother converting the buf data into anything else. Wrap it into a plain.js file, apply some decent "don't repeat yourself" refactoring, and submit a pull request to connect. Seems generally handy. However, note that while convenient, large enough request bodies will require streaming straight to disk at some point so you don't consume all the memory in your node server.
You may try this :
var expressApi= (req, res,params)=>{
console.log('req.body',params);
var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end', function () {
res.write({status:200,message:'read data'});
});
}
You can parse every type to json via set type option
app.use(express.json({ type: ['text/*', '*/json'] }))

Resources