Send multiple variables to Node.js server with JQuery AJAX - javascript

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

Related

How to save a file sent from NodeJS with POST

I created the following function to load a stream file. This stream is sent to the address specified with a POST. At the destination, I have another NodeJS service that with ExpressJS "capture" this POST but I have no idea how I can save the file to the destination.
NodeJS on my PC:
function sendFileToRaspberry(filePath) {
var options = {
method: 'POST',
url: 'http://x.x.x.x:8080/api/print',
qs: {file: fs.createReadStream(filePath)},
headers:
{
'cache-control': 'no-cache'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
}
NodeJS on my Raspberry:
app.post('/api/print', function (req, res) {
ORIGINAL_IP = req.ip.replace("::ffff:", '');
console.log("Received a print request from: " + ORIGINAL_IP);
// Test history data for /api/printer API
var file = req.query.file;
console.log("Test data: " + file);
util.inspect(file);
});
But in the console log I get:
Received a print request from: y.y.y.y
Test data: [object Object]
How can I save this file on Rasp?
You can use a expressjs middleware helper like express-fileupload, multer.
I think, you have use Multipart Form Uploads to upload a file via http POST.
Client side (Your PC)
function sendFileToRaspberry(filePath) {
var options = {
method: 'POST',
url: 'http://x.x.x.x:8080/api/print',
formData: {
file: fs.createReadStream(filePath)
},
headers: {
'cache-control': 'no-cache'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
}

Javascript AJAX SyntaxError: Unexpected token E in JSON at position 0 in ajax + node.js

I am making an AJAX POST request with multiple objects to a node.js server. Although my server sends status code 200, I am still getting the error Javascript AJAX SyntaxError: Unexpected token E in JSON at position 0. Here is my POST request:
var company_id = "some_generic_id";
var president = "obama";
var postData = {
company_id : company_id,
president : president
};
$.ajax({
type: "POST",
url: '/api/test_link',
data: JSON.stringify(postData),
contentType: "application/json; charset=utf-8",
dataType: "json",
data: postData,
success: function(data, status) {
console.log('it worked!')
},
error: function(request, status, error) {
console.log(request);
console.log(status);
console.log(error);
}
});
And here is my server side code:
app.post('/api/test_link', function(req, res) {
console.log('--post data--');
console.log(req.body);
/*
prints out:
--post data--
{ company_id: 'company_id', president: 'obama' }
*/
res.sendStatus(200);
});
Here's an image from my network tab:
Does anyone know what I might be missing or why my postData has invalid syntax?
The docs on ajax call states about dataType option:
The type of data that you're expecting back from the server. "json":
Evaluates the response as JSON and returns a JavaScript object.
Since you're not returning any data from the server, your empty data is parsed as JSON, which produces the error. Simply remove dataType: "json" if you're not returning any data.
add res.writeHead(200, {"Content-Type": "application/json"}); at the beginning of app.post('/api/test_link', function(req, res) { to specify that you wanted response as json format
Remove your
res.sendStatus(200);
Since res.writeHead(200, {'Content-Type': 'application/json'}); will also set your statusCode
So it would be like this
app.post('/api/test_link', function(req, res) {
res.writeHead(200, {'Content-Type': 'application/json'});
console.log('--post data--');
console.log(req.body);
/*
prints out:
--post data--
{ company_id: 'company_id', president: 'obama' }
*/
res.send();
});
I face this error if I'm not using JSON.stringify():
$.post(url, body, res => { ... });
// Error: {message: "Unexpected token e in JSON at position 0"}
$.post(url, JSON.stringify(body), res => { ... });

JSON body always empty in Node.js application

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.

Add parameters to HTTP POST request in Node.JS

I've known the way to send a simple HTTP request using Node.js as the following:
var http = require('http');
var options = {
host: 'example.com',
port: 80,
path: '/foo.html'
};
http.get(options, function(resp){
resp.on('data', function(chunk){
//do something with chunk
});
}).on("error", function(e){
console.log("Got error: " + e.message);
});
I want to know how to embed parameters in the body of POST request and how to capture them from the receiver module.
Would you mind using the request library. Sending a post request becomes as simple as
var options = {
url: 'https://someurl.com',
'method': 'POST',
'body': {"key":"val"}
};
request(options,function(error,response,body){
//do what you want with this callback functon
});
The request library also has a shortcut for post in request.post method in which you pass the url to make a post request to along with the data to send to that url.
Edit based on comment
To "capture" a post request it would be best if you used some kind of framework. Since express is the most popular one I will give an example of express. In case you are not familiar with express I suggest reading a getting started guide by the author himself.
All you need to do is create a post route and the callback function will contain the data that is posted to that url
app.post('/name-of-route',function(req,res){
console.log(req.body);
//req.body contains the post data that you posted to the url
});
If you want to use the native http module, parameters can be included in body this way:
var http = require('follow-redirects').http;
var fs = require('fs');
var options = {
'method': 'POST',
'hostname': 'example.com',
'path': '/foo.html',
'headers': {
},
'maxRedirects': 20
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
var postData = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"examplekey\"\r\n\r\nexamplevalue\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--";
req.setHeader('content-type', 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW');
req.write(postData);
req.end();

How to post to a request using node.js

I am trying to post some json to a URL. I saw various other questions about this on stackoverflow but none of them seemed to be clear or work. This is how far I got, I modified the example on the api docs:
var http = require('http');
var google = http.createClient(80, 'server');
var request = google.request('POST', '/get_stuff',
{'host': 'sever', 'content-type': 'application/json'});
request.write(JSON.stringify(some_json),encoding='utf8'); //possibly need to escape as well?
request.end();
request.on('response', function (response) {
console.log('STATUS: ' + response.statusCode);
console.log('HEADERS: ' + JSON.stringify(response.headers));
response.setEncoding('utf8');
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
When I post this to the server I get an error telling me that it's not of the json format or that it's not utf8, which they should be. I tried to pull the request url but it is null. I am just starting with nodejs so please be nice.
The issue is that you are setting Content-Type in the wrong place. It is part of the request headers, which have their own key in the options object, the first parameter of the request() method. Here's an implementation using ClientRequest() for a one-time transaction (you can keep createClient() if you need to make multiple connections to the same server):
var http = require('http')
var body = JSON.stringify({
foo: "bar"
})
var request = new http.ClientRequest({
hostname: "SERVER_NAME",
port: 80,
path: "/get_stuff",
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(body)
}
})
request.end(body)
The rest of the code in the question is correct (request.on() and below).
Jammus got this right. If the Content-Length header is not set, then the body will contain some kind of length at the start and a 0 at the end.
So when I was sending from Node:
{"email":"joe#bloggs.com","passwd":"123456"}
my rails server was receiving:
"2b {"email":"joe#bloggs.com","passwd":"123456"} 0 "
Rails didn't understand the 2b, so it wouldn't interpret the results.
So, for passing params via JSON, set the Content-Type to application/json, and always give the Content-Length.
To send JSON as POST to an external API with NodeJS... (and "http" module)
var http = require('http');
var post_req = null,
post_data = '{"login":"toto","password":"okay","duration":"9999"}';
var post_options = {
hostname: '192.168.1.1',
port : '8080',
path : '/web/authenticate',
method : 'POST',
headers : {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'Content-Length': post_data.length
}
};
post_req = http.request(post_options, function (res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('Response: ', chunk);
});
});
post_req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
post_req.write(post_data);
post_req.end();
There is a very good library that support sending POST request in Nodejs:
Link: https://github.com/mikeal/request
Sample code:
var request = require('request');
//test data
var USER_DATA = {
"email": "email#mail.com",
"password": "a075d17f3d453073853f813838c15b8023b8c487038436354fe599c3942e1f95"
}
var options = {
method: 'POST',
url: 'URL:PORT/PATH',
headers: {
'Content-Type': 'application/json'
},
json: USER_DATA
};
function callback(error, response, body) {
if (!error) {
var info = JSON.parse(JSON.stringify(body));
console.log(info);
}
else {
console.log('Error happened: '+ error);
}
}
//send request
request(options, callback);
Try including the content length.
var body = JSON.stringify(some_json);
var request = google.request('POST', '/get_stuff', {
host: 'server',
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'application/json'
});
request.write(body);
request.end();
This might not solve your problem, but javascript doesn't support named arguments, so where you say:
request.write(JSON.stringify(some_json),encoding='utf8');
You should be saying:
request.write(JSON.stringify(some_json),'utf8');
The encoding= is assigning to a global variable, so it's valid syntax but probably not doing what you intend.
Probably non-existent at the time this question was asked, you could use nowadays a higher level library for handling http requests, such as https://github.com/mikeal/request. Node's built-in http module is too low level for beginners to start with.
Mikeal's request module has built-in support for directly handling JSON (see the documentation, especially https://github.com/mikeal/request#requestoptions-callback).
var request = google.request(
'POST',
'/get_stuff',
{
'host': 'sever',
**'headers'**:
{
'content-type': 'application/json'
}
}
);

Categories