JSON body always empty in Node.js application - javascript

I am building a simple application using Node.js. On the client, I am sending some JSON data using Ajax to the server with the following code:
var data = {};
data.title = "title";
data.message = "message";
$.ajax({
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
url: '/myresult',
processData: false,
success: function (data) {
console.log('success');
console.log(JSON.stringify(data));
}
});
The server side code handling this request is:
app.post('/myresult', function (req, res) {
var obj = {};
console.log('body: ' + JSON.stringify(req.body));
res.send(req.body);
});
However the console log prints the response bode as empty, i.e. body: {}.
Why is the body value empty and how can it be filled with the title and message?

Express gets a kind help from body-parser.
Use it as a middleware to get the actual body content:
app.use(require('body-parser').urlencoded({extended: true}));
and then leave your code as it was:
app.post('/myresult', function(req, res) {
var obj = {};
console.log('body: ' + JSON.stringify(req.body));
res.send(req.body);
});
I expect this will work for you, but please note bodyParser.json() as well, which might be better suited for your needs.
In addition, what's currently happening is since you have processData: false, it's basically sending this: ({"command":"on"}).toString() which is [object Object] and there's your body parser failing. Try removing processData flag entirely.

Related

Can't get data from client on server-side with Ionic and Express.js

This question might have been ansked before, but i can't seem to find the correct answer for it. I'm working on a Ionic project where i've created another project with Node.js and express.js to handle all my http requests. Both are running on localhost at the moment. When i'm trying to send some data from my client-side to to server-side, the data that i'm getting from the request looks like this when i console.log(req.body):
{ '{"username":"hello#hello.com"}': '' }
I tryed both req.body[username] and so on to get the data, but then it just gets undefined.
My controller for handling the http request looks like this:
$scope.submit = function(){
var username = $scope.username;
console.log($scope.data.username);
$http({
method: 'POST',
url: 'http://localhost:8000/api/users',
data: username,
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Access-Control-Allow-Origin': '*'}
});
Html element
<input type="text" ng-model="data.username" name="name">
Server-side API looks like this:
router.post('/users', function (req, res) {
var username = req.body;
var newUser = new User({
username: username
})
newUser.save(function (err) {
if (err) {
return res.send(500, err);
}
return res.json(200, newUser);
});
});
Server.js bodyparser included
app.use(bodyParser.json());
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
app.use(bodyParser.urlencoded({ extended: true }));
Object have keys and values
{ key: value }
The object on the body is beeing sent in some wrong way since you're sending a object with they key '{"username":"hello#hello.com"}' which has the value ''.
I would recomend fixing how you're posting to your nodejs/express server. But you can get the value by some hacks. Like this.
const body = {'{"username":"hello#hello.com"}': '' }
const keys = Object.keys(body);
const parsed = JSON.parse(keys[0]);
console.log(parsed.username);
https://jsfiddle.net/wejh0fsk/2/
Edit: So what I am doing here is getting all the keys of the object. There's only one key '{"username":"hello#hello.com"}'. Since that key is a string I am parsing it to get a object. Now I have a object
{ username: 'hello#hello.com' }
And finally I'm logging out the username.
The right solution would to fix how your sending your data to the express server.
I don't quite understand your controller. Your ng-model is data.username but then you're putting
var username = $scope.username
Which should be
var username = $scope.data.username // (that's at least what you're binding to in your view)
Also you want to send an object with the post, not just the value
$scope.submit = function(){
var username = $scope.username;
console.log($scope.data.username);
$http({
method: 'POST',
url: 'http://localhost:8000/api/users',
data: { username: username },
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Access-Control-Allow-Origin': '*'}
});
I am not sure on express parsers but I don't know why you're calling the bodyparser twice. The first one should be enough.

req.body.data got undefined in nodejs

My client side
$.post("http://localhost:3000/scrape",
{
data: 'something'
},
function(data, status){
console.log(data);
});
What I do in node.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/scrape', function (req, res) {
console.log(req.body.data)
});
But I got undefined in console.log(req.body.data), any idea why?
Your data must be of json format. since you are using bodyParser.json().
Try setting the http header, Content-type as application/json in your $.post call and send a valid json structure as data
$.ajax({
url: "scrape",
type: "POST",
data: JSON.stringify({ someData : "someData}),
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(data){
console.log(data)
},
error: function(){
console.log('error in sending request')
}
})
console.log(req.body.data)
returns undefined because the data is in req.body you should console.log(req.body)
and add app.use(bodyParser.urlencoded({extended: false})); so that data not in json format can also be parsed.
if you want req.body.data have data then make request like
$.post("http://localhost:3000/scrape",
{
data: {data: 'something'}
},
function(data, status){
console.log(data);
});
also your request is not sending any response you need to do something like
app.post('/scrape', function (req, res) {
console.log(req.body.data)
res.status(200).json({data: reqr.body.data});
});
hope it helps :)

JSON empty array entry disappeared

I defined a JSON, and post it to back end (Node.js).
var imj = {};
imj.images = [];
$.post("/image/uploadImages", imj, function(feedback){
.....
However, what the backend received was
{}
the "images" entry disappeared.
Here's the backend code:
exports.uploadImages = function(req, res) {
if (typeof req.body.images == 'undefined') {
return res.json({
code: 1,
message: "parameter incomplete"
})
}
.....
So the backend return the error {code:1, message:'parameter incomplete'}
Anyone knows why? If I want the backend to receive this empty array, what should I do?
What's the contentType nodeJS is expecting on the back-end? The default contentType for the $.post method is application/x-www-form-urlencoded. If you're endpoint is looking for application/json, you'll always see an empty input.
$.post sends url encoded data, so you need to use $.ajax and specify the content type as well as JSON stringify the data.
var data = {};
data.images = [];
$.ajax({
url: '/image/uploadImages',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(data)
}).done(function(data) {
console.log(data); // { images: [] }
});
On the server side make sure to use a body parser.
var app = require('express')();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/', function (req, res, next) {
console.log(req.body); // { images: [] }
res.json(req.body);
});
app.listen(9000);

Send multiple variables to Node.js server with JQuery AJAX

When I try to log the data that was received by the server it is displayed as one long string. Instead I would like the received data to be seperable as different variables.
Client code
function sendData() {
var datas = { testdata: "TEST", testdata2: "TEST2" };
$.ajax({
url: 'server',
data: JSON.stringify(datas),
type: 'POST',
success: function (data) {
$('#lblResponse').html(data);
},
error: function (xhr, status, error) {
console.log('Error: ' + error.message);
$('#lblResponse').html('Error connecting to the server.');
}
});
}
Server code
var http = require('http');
http.createServer(function (req, res) {
console.log('Request received');
res.writeHead(200, {
'Content-Type': 'text/plain',
'Access-Control-Allow-Origin': '*'
});
req.on('data', function (chunk) {
console.log('GOT DATA!');
var receivedData = JSON.parse(chunk);
console.log(receivedData);
});
res.end("hello");
}).listen(1337);
I would like to be able to call for a single variable to get the value from it in the server. For example console.log(testdata); should display the value "TEST".
By stringifying your data object, you're sending a string to the server as the request body, and it's probably encoded using the "application/x-www-form-urlencoded" encoding.
You probably shouldn't JSON.stringify(datas), just use datas.
You need to parse the request body on the server. For that you could use a module like body

How do I parse my JSON with external middleware now that Express doesn't carry a body parser?

How do I parse my JSON with external middleware now that Express doesn't carry a body parser?
For a while, I was using Express bodyParser to receive and respond to JSON posts to the server. Each time I started up the server, express said something about bodyParser being removed soon, and sure enough, I've updated and now JSON requests seem to be showing null.
So I didn't understand how middleware worked, and had followed an express tutorial to use the body parser. Now, using separate body parser middleware, it seems I'm doing it wrong.
Before, my syntax was:
app.use(express.bodyParser());
Now, with the module body-parser as middleware, it's like this:
app.use(bodyParser.json());
And an example as a whole:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
function listen() {
app.use(bodyParser.json());
app.post('/login', function (req, res) {
var username = req.body.username;
var password = req.body.password;
console.log('User ' + username + ' is attempting login...');
validate(username, password, function (err, result) {
if (err) loginFail(req, res, err);
else loginSucceed(req, res, result);
});
});
app.listen(3333);
}
listen();
I tried express.json() as the middleware, but that triggers the fatal error:
Error: Most middleware (like json) is no longer bundled with Express
and must be installed separately. Please see
https://github.com/senchalabs/connect#middleware.
That link leads to the body-parser middleware that I'm using via app.use(bodyParser.json()).
Update:
Using bodyParser.json() results in no error, but the data values are null:
User undefined is attempting login...
My client code should be fine, but here it is for completeness:
function sendLogin() {
popLogCreds(creds);
var loginCredentials = {
"username": creds.username,
"password": creds.password
};
console.log("Sending login credentials: " +
JSON.stringify(loginCredentials, null, 4));
request = $.ajax({
url: "http://54.186.131.77:3333/login",
type: "POST",
crossDomain: true,
data: loginCredentials,
dataType: "json",
error: function () {
postError("Uh Oh! The Officeball server is down.");
},
success: function (data) {
var ParsedData = data;
sessionStorage.username = creds.username;
sessionStorage.password = creds.password;
sessionStorage.fname = ParsedData.fname;
sessionStorage.lname = ParsedData.lname;
sessionStorage.rank = ParsedData.rank;
console.log(sessionStorage);
window.location.replace("app.html");
}
});
}
Which results in:
Sending login credentials: {
"username": "jonathan#evisiion.com",
"password": "J******!"
}
And then the result is the POST's error output, which is, as above:
error : function () {
postError("Uh Oh! The Officeball server is down.");
}
Don't take that error message literally. Just means an error happened. The server is, in fact, getting that request, as shown up above.
By default, $.ajax() sends data URL-encoded as mentioned in the description of the processData option:
By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded".
The body-parser that corresponds to that Content-Type and format is urlencoded():
app.use(bodyParser.urlencoded());
If you'd rather use JSON for the request, you'll need to provide the data already formatted as such along with a matching contentType that bodyParser.json() recognizes:
request = $.ajax({
url: "http://54.186.131.77:3333/login",
type: "POST",
crossDomain: true,
data: JSON.stringify(loginCredentials),
contentType: 'application/json',
dataType: 'json'
// ...
});
Note for cross-domain: With these modifications, the server will have to handle preflight OPTIONS requests for the route.
And, note that a bodyParser isn't needed for HEAD or GET requests as the data is included in the URL rather than the body. Express parses that separately into req.query.
In your node code,
make sure you put these two lines of code
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyparser.urlencoded({ extended: false }));
app.use(bodyparser.json());
......then your other code follows..
enjoy...

Categories