Nodejs) Body of post request seems strange - node.js

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).

Related

ajax requests to Node.js

In my app.js file in Node.js I have this:
app.use(express.json());
which I thought was good enough but whenever I submit data via jQuery/Ajax the response is an empty object.
After doing the below however, it now get the data from req.body. But, I thought that in the newer versions of Express it was not necessary to do this anymore?
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
The Ajax request:
$.ajax({
url: 'http://localhost:8000/api/v1/endpoint',
method: 'POST',
data: {key: key}
})
.done(function(data) {
console.log(data)
})
.fail(function(data) {
console.log(data);
})
The issue is with how you're making your ajax requests. express.json expects the Content-Type of the request to be JSON and I believe if you check your network call on the browser DevTools you'll see that the Content-Type of your request is not JSON.
You need to set the headers in your ajax request and also send valid JSON data like so
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({key: key})
Then the express.json middleware will handle the request and you won't need to use the bodyParser lines of code you're using.

Parse XML body from HTTP Push request with Express & Node.js, using body-parser-xml

I need to process a HTTP push request using Node.js express.
The request is sending the body in XML format, that's why I chose the body-parser-xml package for parsing.
My problem is, that the body isn't properly parsed – I guess because the package doesn't recognize the mime type of the transferred body.
The endpoint:
const express = require('express');
const bodyParser = require('body-parser');
require('body-parser-xml')(bodyParser);
const app = express();
const PORT = 8085;
app.use(express.urlencoded({ extended: true }));
app.use(bodyParser.xml({
limit:'25MB'
}));
app.post('/feed', function (req, res, body) {
console.log(req.headers);
console.log(req.body);
res.status(200).end();
});
The output:
{
host: 'localhost:8085',
accept: '*/*',
'x-meta-feed-type': '1',
'x-meta-feed-parameters': 'feed params',
'x-meta-default-filename': 'filename.xml',
'x-meta-mime-type': 'text/xml',
'content-length': '63'
encoding: 'UTF-8',
connection: 'Keep-Alive'
}
{
'<data id': '"1234"><name>Test</name><title>Test1234</title></data>'
}
I'm not able to change the request itself (it's external), only the Node.js endpoint.
Any idea how to process the content properly?
Thanks for your help!
The request has apparently been parsed by the
app.use(express.urlencoded({ extended: true }));
middleware, which means that it must have had Content-Type: application/x-www-form-urlencoded. Remove the two app.use lines, because they make "global" body-parsing decisions (for every request), whereas you need a special treatment only for one type of request.
If you instantiate the XML body parser with the "non-standard" (that is, wrong) type, it will parse the content as XML:
app.post('/feed',
bodyParser.xml({type: "application/x-www-form-urlencoded"}),
function (req, res) {
console.log(req.headers);
console.log(req.body);
res.status(200).end();
});

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);
});

xxx-form-encoded to application/json

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.

node.js body-parser bad interpretation of Content-Type:x-www-form-urlencoded and Form-data JSON

I have a client request with
Content-type: Content-Type:application/x-www-form-urlencoded; charset=UTF-8
And Form-Data like this (json):
{"jsonrpc":"2.0","method":"print","params":{"id":"lp0","doc":"<section>
<p> sitedemo </p><br><barcode> CLODGCGMM
</barcode><br><br><hr><drawer></drawer><br></section>"},"id":1501151330950}
The node.js server use body-parser middleware like this :
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
A console.log(request.body) give me something like this:
{ '{"jsonrpc":"2.0","method":"print","params":{"id":"lp0","doc":"<section>
<p>': '',
'nbsp;': '',
'nbsp;sitedemo': '',
'nbsp;':'',
' </p><br><barcode>':''
'.......}'}
A json object is built having keys made by lines and values null .
How can i retrieve the exact object send by client (i have no access to client)
Thank you.
The client is broken when it's stating in the headers that the request body is URL-encoded but it's sending JSON.
If that's really the situation, you need to prevent those requests from being decoded by body-parser, and do the decoding manually.
Instead of this:
app.use(bodyParser.urlencoded({ extended: true }));
Try this:
app.use(
bodyParser.raw({ type : 'application/x-www-form-urlencoded' }),
function(req, res, next) {
try {
req.body = JSON.parse(req.body)
} catch(e) {
req.body = require('qs').parse(req.body.toString());
}
next();
}
);

Resources