how to get formated JSON data from node.js server? - javascript

I wrote code to get the data from HTML page (client) to server.js (node.js) and it will save JSON file locally.
This is my server.js :
var http = require('http');
var util = require('util')
var fs = require('fs');
http.createServer(function (req, res) {
if (req.method == 'POST') {
console.log("POST");
var body = '';
req.on('data', function (data) {
body += data;
console.log("Partial body: " + body);
fs.writeFile("./text1.json", JSON.stringify(body, null, 4), (err) => {
if (err) {
console.error(err);
return;
}
console.log("File has been created");
});
});
req.on('end', function () {
console.log("Body: " + body);
});
res.writeHead(200, {'Content-Type': 'text/html','Access-Control-Allow-Origin': '*'});
res.end('callback(\'{\"msg\": \"OK\"}\')');
}
else
{
console.log("GET");
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('callback(\'{\"msg\": \"OK\"}\')');
}
}).listen(8090);
console.log('Server running on port 8090');
and Here my HTML code from where I am sending data :
data_frame = {
"frame": i,
"Objects_classname" : obj.getObjects()[1].text,
"x_val":obj.left,
"y_val":obj.top,
"width":obj.width,
"height" : obj.height
}
$.ajax({
url: 'http://127.0.0.1:8090',
// dataType: "jsonp",
data: data_frame,
type: 'POST',
jsonpCallback: 'callback', // this is not relevant to the POST anymore
success: function (data) {
var ret = JSON.parse(JSON.stringify(data));
//$('#layer1').html(ret.msg);
//console.log(ret);
console.log('Success: ')
},
error: function (xhr, status, error) {
console.log('Error: ' + error.message);
// $('#layer1').html('Error connecting to the server.');
},
});
});
So the output I am getting is like this in JSON file :
"output%5Bframe%5D=11&output%5BObjects_classname%5D=car2&output%5Bx_val%5D=518.94958&output%5By_val%5D=130.03093&output%5Bwidth%5D=65.58593999999994&output%5Bheight%5D=104.8877"height%5D=213.56171"
but I wants this format :
var data = [
{
"Frame_count":1,
output:[
{
"Objects_classname":"car1",
"x_val":82.9883,
"y_val":197.56245,
"width":316.03088,
"height":197.45451
},
{
"Objects_classname":"car2",
"x_val":522.4823,
"y_val":170.47263,
"width":64.66687,
"height":61.78085
},
],
"Total_objects_detected":2,
},
{
"Frame_count":2,
output:[
{
"Objects_classname":"car1",
"x_val":78.9991,
"y_val":189.48058,
"width":327.41028,
"height":198.80226
}
],
"Total_objects_detected":1,
}]
SO how can i achieve this.
I tried with jsonstringify(body, null, 4) but this is not working.

Try this as your server:
let express = require('express'),
fs = require('fs'),
bodyParser = require('body-parser'),
app = express(),
port = process.env.PORT || process.argv[2] || 8080;
app.use(bodyParser.json());
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.post('/', function (req, res) {
console.log(req.body);
fs.writeFile("./text1.json", JSON.stringify(req.body, undefined, 4), (err) => {
if (err) {
console.error(err);
res.send(err);
}
console.log("File has been created");
res.json(req.body);
});
});
app.listen(port, function () {
console.log('body-parser demo is up on port: ' + port);
});
This is you index.html file put it in same folder as your server.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script type="text/javascript">
var data_frame = {
"Objects_classname": "car1",
"x_val": 82.9883,
"y_val": 197.56245,
"width": 316.03088,
"height": 197.45451
};
$.ajax({
url: '/',
data: JSON.stringify(data_frame),
type: 'POST',
contentType: 'Application/json',
success: function(data) {
var ret = JSON.parse(JSON.stringify(data));
console.log('Success: ')
},
error: function(xhr, status, error) {
console.log('Error: ' + error.message);
}
});
</script>
<body>
</body>
</html>

Related

How to POST JSON data to server using AJAX jQuery

Keep getting error when trying to post 'order' JSON data to JSON file on Node.js server
GET request works fine but 'Error' function executes instead of the 'success' function when trying to do a POST request. Am I missing anything? Do I need to use php?
The dev tools console shows the following error message:
POST http://.../orders.json 405 (Method Not Allowed) jquery.js:10109
$("#add-order").on("click", function()
{
var order =
{
name: $name.val(),
food: $food.val()
};
$.ajax(
{
type: "POST",
url: "orders.json",
dataType: "json",
contentType: "application/json",
data: JSON.stringify(order),
processData: false,
success: function(newOrder)
{
alert("success");
$orders.append("<li>Name: " + newOrder.name +", food: " + newOrder.food + "</li>");
},
error: function()
{
alert("Error posting order");
}
});
});
Node js server
const http = require("http");
const fs = require("fs");
const port = 3000;
const server = http.createServer(function(request, response)
{
response.writeHead(200, { "Conent-Type": "text/json" })
fs.readFile("orders.json", function(error, data)
{
if (error)
{
response.writeHead(404);
response.write("Error: File Not Found");
}
else response.write(data);
response.end();
})
});
server.listen(port, function(error)
{
if (error) console.log("Something went wrong. Error: ", error);
else console.log("server is listening to port " + port);
})
var http = require('http');
var requestListener = function(req, res) {
console.log("" + req.method)
if (req.method === "POST") {
let data = '';
req.on('data', chunk => {
data += chunk;
})
req.on('end', () => {
console.log(data)
res.end("received");
})
}
res.writeHead(200);
res.end('Hello, World!' + req.method);
}
var server = http.createServer(requestListener);
server.listen(3000, function() {
console.log("Listening on port 3000")
});
//curl -d '{"name":"1","age":"2"}' -H 'Content-Type: application/json' localhost:3000
//Output
/*
Listening on port 3000
POST
undefined
{"name":"1","age":"2"}
*/
Or you can explore express or any other middle ware for easy parsing and handling.

Server side code does not recognize my req.body.variable, stating that it is undefined

Im creating a web application that should send info from the client side to the server side every time a specific button is pressed. When I press the button, the terminal continues to tell me that the value I am trying to pass through the post request body is undefined.
Client side code (Where button is called from) -
function upvote(elem) {
var parentID = elem.parentNode.id;
console.log('Upvote button was clicked' + parentID);
fetch('/upvote', { //This is called to pass the body data to server side code
method: 'post',
body: JSON.stringify({
id: parentID
})
})
.then(function(res) {
if(res.ok) {
console.log('Click was recorded');
return;
}
throw new Error('Request failed.');
})
.catch(function(error) {
console.log(error);
});
}
function downvote(elem){
var parentID = elem.parentNode.id;
console.log('Downvote button was clicked');
fetch('/downvote', { //This is called to pass the body data to server side code
method: 'POST',
body: JSON.stringify({
id: parentID })
})
.then(function(res) {
if(res.ok) {
console.log('Click was recorded');
return;
}
throw new Error('Request failed.');
})
.catch(function(error) {
console.log(error);
});
}
setInterval(function() {
fetch('/ranking', {method: 'GET'})
.then(function(response) {
if(response.ok) return response.json();
throw new Error('Request failed.');
})
.then(function(data) {
})
.catch(function(error) {
console.log(error);
});
}, 1000);
My app.js (Server side code) --
const bodyParser = require('body-parser');
const mysql = require('mysql');
const path = require('path');
const app = express();
const {getLoginPage, login} = require('./routes/index');
const {players, questionsPage, upvoteQues, downvoteQues, ranking, addQuestionsPage, addQuestion, deleteQuestion, editQuestion, editQuestionPage} = require('./routes/question'); //All my routes
const port = 5000;
const db = mysql.createConnection ({
host: 'localhost',
user: 'root',
password: '',
database: ''
});
// connect to database
db.connect((err) => {
if (err) {
throw err;
}
console.log('Connected to database');
});
global.db = db;
// configure middleware
app.set('port', process.env.port || port); port
app.set('views', __dirname + '/views'); folder to render our view
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(__dirname + '/public'));
app.get('/', getLoginPage);
app.get('/questions', questionsPage);
app.get('/add', addQuestionPage);
app.get('/edit/:id', editQuestionPage);
app.get('/delete/:id', deleteQuestion);
app.get('/ranking', ranking);
app.post('/', login);
app.post('/add', addQuestion);
app.post('/edit/:id', editQuestion);
app.post('/upvote', upvoteQues); //This is then used
app.post('/downvote', downvoteQues); //This is then used
// set the app to listen on the port
app.listen(port, () => {
console.log(`Server running on port: ${port}`);
});
My question.js (More server side code, just separated into a different file)
const fs = require('fs');
module.exports = {
questionsPage:(req, res) =>{
let query = "SELECT * FROM `Questions` ORDER BY Ranking DESC";
db.query(query, (err, result) => {
if (err) {
console.log('Query error');
res.redirect('/');
}
res.render('questions.ejs', {
title: "JustAsk!",
questions: result,
});
});
},
upvoteQues: (req, res) => {
console.log(req.body.id); //Error here
let updateQuery = "UPDATE `Questions` Ranking = Ranking+1 WHERE QuestionID = '"+ req.body.id + "'" //Error here
db.query(updateQuery, (err, result) => {
if(err){
console.log('Query error');
res.redirect('/players')
}
});
},
downvoteQues: (req, res) =>{
console.log(req.body.id); //Error here
let updateQuery = "UPDATE `Questions` Ranking = Ranking+1 WHERE QuestionID = '"+ req.body.id + "'" //Error here
db.query(updateQuery, (err, result) => {
if(err){
console.log('Query error');
res.redirect('/players')
}
});
},
ranking: (req, res) => {
let query = "SELECT * FROM `Questions` ORDER BY Ranking DESC";
db.query(query, (err, result) => {
if (err) {
console.log('Query error');
}
res.send(result);
});
}
};
The body should be in JSON format, not a string.
body: JSON.stringify({
id: parentID
})
change to:
body: { id: parentID }
and content type should be 'application/json` like below.
fetch('/url', {
method: 'POST',
body: {id: parentID },
headers: {
"Content-Type": "application/json",
}
})

Node.js - jQuery. Get PDF from server and display on front-end

I'm bit stuck here. My intent is to first get all files (filenames) from a static folder + subfolders and list all on front-end.
When user clicks one of the filenames (mostly pdf's), the server returns the selected items content.
I'm able to send the pdf data as binary to front-end, but how could I display the data in a new tab with js/jQuery?
so far..
Server.js -
// Importing and initializing npm/node plugins
var app = require('express')();
var server = require('http').createServer(app);
var logger = require('morgan');
var bodyParser = require('body-parser');
var pdf = require('express-pdf');
var cors = require('cors');
var fs = require('fs');
// Import config settings
var config = require('./config.json');
app.use(logger('dev'));
// Allow application/x-www-form-urlencoded and application/json
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json({
limit: '50mb'
}));
app.use(cors());
app.use(pdf);
app.get('/getfiles', function (req, res) {
var dir = config.sourceDir;
var foundFiles = [];
fs.readdir(dir, function (err, files) {
if (err) {
console.log('Error reading ' + dir);
process.exit(1);
}
console.log('Listing files in Directory ' + dir);
files.forEach(function (f) {
foundFiles.push(f);
});
res.json(foundFiles);
});
});
app.post('/showfiles', function (req, res) {
var file = req.body.filename;
var dir = config.sourceDir;
fs.readFile(dir + file, function (err, data) {
res.contentType('application/pdf');
res.send(data);
});
});
// Open server in port
server.listen(config.port, function () {
console.log('Server listening on port: ' + config.port);
});
module.exports = app;
On front-end -
$(function () {
getFiles();
});
function getFiles() {
$.ajax({
type: "GET",
url: "http://localhost:3000/getfiles",
contentType: "application/json; charset=utf-8",
crossDomain: true,
dataType: "json",
success: function (data, status, jqXHR) {
if (data) {
$.each(data, function (index, value) {
$("#listContainer1").append("<li><a href='#' onclick='showFile(this)'>" + value + "</a></li>");
});
}
},
error: function (jqXHR, status) {
console.log("Error fetching data");
}
});
}
function showFile(file) {
$.ajax({
type: "POST",
data: JSON.stringify({
"filename": $(file).text()
}),
url: "http://localhost:3000/showfiles",
contentType: "application/json; charset=utf-8",
crossDomain: true,
dataType: "application/pdf",
success: function (data, status, jqXHR) {
if (data) {
var file = new Blob([data], {
type: 'application/pdf'
});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
},
error: function (jqXHR, status) {
console.log("Error showing file");
}
});
}
But this keeps falling into the "Error showing file" pit. :(
EDIT:
The first error was corrected by removing the "application/pdf" from post, but now its opening an empty pdf with correct page limit
On the server, change the file fetch code to this:
app.get('/showfiles/:filename', function (req, res) {
var options = {
root: config.sourceDir
};
var fileName = req.params.filename;
res.sendFile(fileName, options, function (err) {
if (err) {
// Handle error
} else {
// Handle success
}
});
});
So I switched the method to GET and used the built-in sendFile method in Express. Then on the front end it's much easier. You can get rid of the showFile function and just update the getFiles function:
function getFiles() {
$.ajax({
type: "GET",
url: "http://localhost:3000/getfiles",
contentType: "application/json; charset=utf-8",
crossDomain: true,
dataType: "json",
success: function (data, status, jqXHR) {
if (data) {
$.each(data, function (index, value) {
$("#listContainer1").append('<li>' + value + '</li>');
});
}
},
error: function (jqXHR, status) {
console.log("Error fetching data");
}
});
}
Code has not been tested and most likely has mistakes, but should give you a gist of another way you can tackle the problem.

How to send a POST request from node.js Express?

Could someone show me the simplest way to send a post request from node.js Express, including how to pass and retrieve some data? I am expecting something similar to cURL in PHP.
var request = require('request');
function updateClient(postData){
var clientServerOptions = {
uri: 'http://'+clientHost+''+clientContext,
body: JSON.stringify(postData),
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
}
request(clientServerOptions, function (error, response) {
console.log(error,response.body);
return;
});
}
For this to work, your server must be something like:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())
var port = 9000;
app.post('/sample/put/data', function(req, res) {
console.log('receiving data ...');
console.log('body is ',req.body);
res.send(req.body);
});
// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);
As described here for a post request :
var http = require('http');
var options = {
host: 'www.host.com',
path: '/',
port: '80',
method: 'POST'
};
callback = function(response) {
var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
});
}
var req = http.request(options, callback);
//This is the data we are posting, it needs to be a string or a buffer
req.write("data");
req.end();
you can try like this:
var request = require('request');
request.post({ headers: {'content-type' : 'application/json'}
, url: <your URL>, body: <req_body in json> }
, function(error, response, body){
console.log(body);
});
in your server side the code looks like:
var request = require('request');
app.post('/add', function(req, res){
console.log(req.body);
request.post(
{
url:'http://localhost:6001/add',
json: {
unit_name:req.body.unit_name,
unit_price:req.body.unit_price
},
headers: {
'Content-Type': 'application/json'
}
},
function(error, response, body){
// console.log(error);
// console.log(response);
console.log(body);
res.send(body);
});
// res.send("body");
});
in receiving end server code looks like:
app.post('/add', function(req, res){
console.log('received request')
console.log(req.body);
let adunit = new AdUnit(req.body);
adunit.save()
.then(game => {
res.status(200).json({'adUnit':'AdUnit is added successfully'})
})
.catch(err => {
res.status(400).send('unable to save to database');
})
});
Schema is just two properties unit_name and unit_price.
I use superagent, which is simliar to jQuery.
Here is the docs
And the demo like:
var sa = require('superagent');
sa.post('url')
.send({key: value})
.end(function(err, res) {
//TODO
});
Try this. It works for me.
const express = require("express");
const app = express();
app.use(express.json());
const PORT = 3000;
const jobTypes = [
{ id: 1, type: "Interior" },
{ id: 2, type: "Etterior" },
{ id: 3, type: "Roof" },
{ id: 4, type: "Renovations" },
{ id: 5, type: "Roof" },
];
app.post("/api/jobtypes", (req, res) => {
const jobtype = { id: jobTypes.length + 1, type: req.body.type };
jobTypes.push(jobtype);
res.send(jobtype);
});
app.listen(PORT, console.log(`Listening on port ${PORT}....`));

Take Binary data and save it as an .mp3 file Javascript

So I have a Node.js script and a Javascript file communicating with each other, and everything works except the Node.js is supposed to return data for an .mp3 file.
The data is binary, it looks like gibberish, how would I take that data it returns and allow the user to download it on a webpage using Javascript?
It gets data using http.responseText by the way.
Node.js Code
//initilization
var querystring = require('querystring');
var http = require('http');
var url = require('url');
var fileSystem = require('fs');
var path = require('path');
var util = require('util');
//convert function
function convert(voiceToUse, textToConvert, response)
{
console.log("Sending Convert Request...");
//data to send as a query
var data = querystring.stringify(
{
username: 'user',
password: 'pass',
action: 'convert',
voice: voiceToUse,
text: textToConvert
});
//options to use
var options = {
host: 'ws.ispeech.org',
port: 80,
path: '/api/rest/1.5',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
//http post request
var req = http.request(options, function (res)
{
res.setEncoding('utf8');
res.on('data', function (chunk)
{
console.log("Body: " + chunk);
var fileId = chunk.substr(chunk.indexOf("fileid") + 7);
console.log("Converting File...");
download(fileId.substr(0, fileId.search("&")), response);
});
});
req.on('error', function (e)
{
console.log('problem with request: ' + e.message);
});
req.write(data);
req.end();
}
//download function
function download(id, response)
{
//data to send as a query
var data = querystring.stringify(
{
username: 'user',
password: 'pass',
action: 'download',
fileid: id
});
//options to use
var options = {
host: 'ws.ispeech.org',
port: 80,
path: '/api/rest/1.5',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
//http post request
var req = http.request(options, function (res)
{
res.on('data', function (chunk)
{
if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1)
{
console.log("Downloading Chunk...");
/*var fs = require('fs'),
str = 'string to append to file';
fs.open('test.mp3', 'a', 666, function (e, id)
{
fs.write(id, chunk, 0, chunk.length, 0, function ()
{
fs.close(id, function ()
{
});
});
});*/
response.write(chunk, "binary");
}
else
{
download(id, response);
}
});
res.on('end', function ()
{
if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1){
response.end();
}
});
});
req.on('error', function (e)
{
console.log('problem with request: ' + e.message);
});
req.write(data);
req.end();
}
http = require('http');
fs = require('fs');
server = http.createServer( function(req, res) {
console.dir(req.param);
if (req.method == 'POST') {
console.log("POST");
var body = '';
req.on('data', function (data) {
body += data;
console.log("Partial body: " + body);
});
req.on('end', function () {
console.log("Body: " + body);
if(body){
convert('engfemale1', body, res);
res.writeHead(200, {
'Content-Type': 'audio/mp3',
'Content-Disposition': 'attachment; filename="tts.mp3"'
});
}
});
}
});
port = 8080;
server.listen(port);
console.log('Listening at port ' + port);
Javascript code
console.log('begin');
var http = new XMLHttpRequest();
var params = "text=" + bodyText;
http.open("POST", "http://supersecretserver:8080", true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//http.setRequestHeader("Content-length", params.length);
//http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {
console.log('onreadystatechange');
if (http.readyState == 4 && http.status == 200) {
alert(http.responseText);//response text is binary mp3 data
}
else {
console.log('readyState=' + http.readyState + ', status: ' + http.status);
}
}
console.log('sending...')
http.send(params);
console.log('end');
You could try using data URLs:
mp3 download
Not the best browser support though.
It is also possible to use data URLs directly in audio tags.
A better solution would be to save the mp3 on your server somewhere and return a link to it for a mp3 player to use.

Categories