xxx-form-encoded to application/json - node.js

My login functionalities in the backend accepts the parameters in xxx-form-encoded format from POSTMAN .. I am getting error when I change the format to application/json . Any thoughts on how to receive the request.body ?
authenticate: function(req, res, next) {
userModel.findOne({email:req.body.email}, function(err, userInfo){
if (err) {
next(err);
} else {
console.log(`The bcrypt value: ${bcrypt.compareSync(req.body.password, userInfo.password)}`)
if(userInfo != null && bcrypt.compareSync(req.body.password, userInfo.password)) {
const token = jwt.sign({id: userInfo._id}, req.app.get('secret'), { expiresIn: '1h' });
res.json({status:"success", message: "user found!!!", data:{user: userInfo, token:token}});
}else{
res.json({status:"error", message: "Invalid email/password!!!", data:null});
}
}
});
}

I think you need to add a middleware which parses your request body to json.
You can use body-parser to acheive it.
if you are using express you can do this to acheive it:
var express = require("express");
var bodyParser = require("body-parser");
var app = express();
app.use(bodyParser.json({}));//this line is required to tell your app to parse the body as json
app.use(bodyParser.urlencoded({ extended: false }));
From body-parser docs :
bodyParser.urlencoded([options])
Returns middleware that only parses urlencoded bodies and only looks
at requests where the Content-Type header matches the type option.
This parser accepts only UTF-8 encoding of the body and supports
automatic inflation of gzip and deflate encodings.
A new body object containing the parsed data is populated on the
request object after the middleware (i.e. req.body). This object will
contain key-value pairs, where the value can be a string or array
(when extended is false), or any type (when extended is true).
Read body-parser documentation for details.

Related

req.body returns an empty object eventhough data is passed through form

this is my index.js code and it returns an empty object even though data is passed on from the front-end
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());
app.use(express.json());
app.post("/api/register", (req, res) => {
console.log(req.body);
res.json({ status: "ok" });
});
app.listen(8000, () => {
console.log("listening on port 8000 . . . ");
});
For the specific case you're talking about, you usually need oa body parser to be able to access the form input fields. The minimum example that I advice you to build above it is the following:
// parse requests of content-type - application/json
app.use(express.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));
Some other hints
Make sure that the request is being submitted with the header Content-Type: application/x-www-form-urlencoded or Content-Type: application/json
Check if there any CORS problems
Here's More reference for you
The main reason this does not work is
some how the data passed in body is in text format while req.body is
expecting json data
make sure to double chek the 'Content-Type':'application/json' is set on the request headers
if you are using multipart/form-data or require a file upload from frontend you will need a multer as middleware for your post/patch requests, otherwise you can set your frontend to send application/json
[edit]
this line looks missing from your index.js
app.use(express.urlencoded({extended: true}))

Body-parser fails to/do not parse urlencoded parameters from GET request

I'm creating a web platform with a Nodejs server. I'm trying to retrieve urlencoded data sent from my front but can't manage to.
How I send the GET request :
xhr.open("GET", address + "?limit=1&offset=1",true);
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(null);
xhr.addEventListener("readystatechange", processRequest, false);
On the server side :
const bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: true });
app.get('/guid_list', urlencodedParser, function (req, res) {
console.log(req.body.limit);
console.log(req.body.offset);
var headerjwt = HeaderGetJWT(req);
...
}
I have no problem retrieving the jwt token I'm sending, but always get undefined for urlencoded parameters.
I was wondering if I should use multipart content type instead, since I'm sending both a token and urlencoded data ? And maybe "multer" module in that case, since body-Parser does not support that content type.
I would suggest accessing your parameters in Node.js as follows (since they are being passed as query parameters):
app.get('/guid_list', parser, function (req, res) {
console.log("req.query.limit:", req.query.limit);
console.log("req.query.offset:", req.query.offset);
});
or just log all parameters:
app.get('/guid_list', parser, function (req, res) {
console.log("req.query:", req.query);
});

nodeJS Express: express.urlencoded() empty req.body

I have an API that works as expected from all incoming requests using application/json request. But recently I encounter the need to process a POST request from x-www-form-urlencoded and the body of the request is always empty.
I test the API using POSTMAN and works great when I send the request using the option raw with JSON(application/json). But when send data using x-www-form-urlencoded the body is empty.
The route for the POST is app/api/sensor, and the files are the following:
app.js
var express = require('express');
var app = express();
.......
app.use(express.json());
app.use(express.urlencoded()); // THIS SHOULD WORK!
......
sensor.js POST
......
sensorRoute.post('/', (req, res, next) => {
console.log(req.body);
const temperature = req.body.temperature;
console.log(temperature);
if (!temperature) {
return res.status(400).send({'res': 'Missing data'});
} else {
return res.status(200).send({'res': 'OK'});
}
});
....
The expected result should show the data that is been send using postman in the req.body and not an empty object, and work the same as the application/jason.
change
app.use(express.urlencoded());
to
app.use(bodyParser.urlencoded({
extended: true
}));
The extended option allows to choose between parsing the URL-encoded data with the querystring library (when false) or the qs library (when true). The "extended" syntax allows for rich objects and arrays to be encoded into the URL-encoded format, allowing for a JSON-like experience with URL-encoded. For more information, please see the qs library.
Defaults to true, but using the default has been deprecated. so add the option extended: true

Nodejs) Body of post request seems strange

I want to send a x-www-form-urlencoded request for the server. I give a json value for it like {username: 'asd', password: '12345'}.
Angular:
...
let headers: HttpHeaders = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
this._http.post('/api/authentication', form.value, {headers: headers, observe: 'response'}).subscribe((response:HttpResponse<Object>) => {
console.log(response); // response body {'{"username":"asd","password":"12345"}' : ""}
});
...
So I get something strange from back-end and I don't really understand what to change in my implementation to make this work like the input he got.
Nodejs (express):
//server.js
...
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true}));
...
--
//api/.../authentication.js
...
router.post('/', (req, res) => {
let post = req.body;
console.log( req.body); //same strange hash: {'{"username":"asd","password":"12345"}' : ""}
res.status(201).json(req.body);
});
...
Http header application/x-www-form-urlencoded means sending a x-www-form-urlencoded request to the server, that's correct.
However, bodyParser.json
only parse request type application/json(default value).
Returns middleware that only parses json and only looks at requests where the Content-Type header matches the type option. Type defaults to application/json.
So it is not correct.
You should send application/json request.
Or you should parse it as application/x-www-form-urlencoded, then decode the content (json).

Mailgun webhook POST body seems empty

I'am trying to handle http post message from Mailgun bounce webhook. When sending it to Mailgun's Postbin service all data is found of course. But I'm now sending that POST to my localhost server for development purposes and all I get is empty json array. I use Test Webhook.
Intent is to keep this simple as possible besides our main service. That for I started using nodejs/expressjs to create stand alone webservice to work as relay to receive POST messages of email bounces from Mailgun and inform admins about bounced email addresses.
Now I can't figure why I don't get the same data as is visible in Postbin.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mailgun = require('mailgun-js')({apiKey: 'key-...', domain: 'mymailgundomain.com'});
app.use(bodyParser.urlencoded({
extended: true
}));
function router(app) {
app.post('/webhooks/*', function (req, res, next) {
var body = req.body;
if (!mailgun.validateWebhook(body.timestamp, body.token, body.signature)) {
console.error('Request came, but not from Mailgun');
res.send({ error: { message: 'Invalid signature. Are you even Mailgun?' } });
return;
}
next();
});
app.post('/webhooks/mailgun/', function (req, res) {
// actually handle request here
console.log("got post message");
res.send("ok 200");
});
}
app.listen(5000, function(){
router(app);
console.log("listening post in port 5000");
});
I'm running this from Mailgun's Test Webhook using url like http://mylocalhostwithpublicip.com:5000/webhooks/mailgun
Code structure is copied from https://github.com/1lobby/mailgun-js. Probably I'm missing something fundamental here as I can't figure it out myself.
The reason you're not seeing req.body populated is because the body-parser module does not support multipart/form-data requests. For those kinds of requests you need a different module such as multer, busboy/connect-busboy, multiparty, or formidable.
If your content-type (shown by logging console.dir(req.headers['content-type'])) is 'application/x-www-form-urlencoded', and you're using body-parser, try adding the following line:
bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))
to make it work with multer, you can use .any() (version 1.1.0)
for me it worked like this: (assuming multer is included and declared as "multer")
post('/track', multer.any(),function(req, res){
//if body is a string, parse the json
var data=(typeof req.body=='string')?JSON.parse(req.body):req.body;
//if data is an object but you can't verify if a field exists with hasOwnProperty, force conversion with JSON
if(typeof data=='object' && typeof data.hasOwnProperty=='undefined')
data=JSON.parse(JSON.stringify(data));
//data is your object
});
var multer = require('multer');
var msg = multer();
post('/track', msg.any(), function(req, res){
console.log(req.body);
}
I make a custom parser for get data in req.body when the Content-type = 'multipart/alternative'
https://github.com/josemadev/Multiparser/

Resources