Passing a JSON object from clientside JavaScript to NodeJS - javascript

I have a webpage which creates a JSON object based on user input. I would like to then somehow allow the user to submit this JSON object to a NodeJS script for processing/insertion into a MySQL database. However, I'm really not sure how to do something like this -- the best I can come up with is some form of a POST, but I'm not sure where to start with this.
Because I don't know what such a method would be described as, I haven't had much success in locating any tutorials or other resources online.
Could anyone suggest some articles or documentation to look at that would be relevant to something like this? Or, at least, tell me what to search for? Thanks.
EDIT: This is the code I am trying to get working at the moment. I'm just trying to convert the POST data type from string to JSON on both sides.
Serverside:
var express = require('express');
var fs = require('fs');
var app = express();
app.use(express.bodyParser());
app.get('/', function(req, res){
console.log('GET /')
//var html = '<html><body><form method="post" action="http://localhost:3000">Name: <input type="text" name="name" /><input type="submit" value="Submit" /></form></body>';
var html = fs.readFileSync('index.html');
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(html);
});
app.post('/', function(req, res){
console.log('POST /');
console.dir(req.body);
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('thanks');
});
port = 8080;
app.listen(port);
console.log('Listening at http://localhost:' + port)
Clientside:
<html>
<body>
<form method="post" action="http://localhost:8080">
Name: <input type="text" name="name" />
<input type="submit" value="Submit" />
</form>
<script type="text/JavaScript">
console.log('begin');
var http = new XMLHttpRequest();
var params = "text=stuff";
http.open("POST", "http://localhost: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);
}
else {
console.log('readyState=' + http.readyState + ', status: ' + http.status);
}
}
console.log('sending...')
http.send(params);
console.log('end');
</script>
</body>
</html>

Here is a very basic example using jQuery to do the post request and an express app. I think it should be a decent starting point.
// client side, passing data to the server
$.post("/foo/", { data : { foo : "bar" } }, function(temp) {
// temp === "I am done";
});
// serverside app.js
var express = require("express");
var app = express();
// will parse incoming JSON data and convert it into an object literal for you
app.use(express.json());
app.use(express.urlencoded());
app.post("/foo/", function(req, res) {
// each key in req.body will match the keys in the data object that you passed in
var myObject = req.body.data;
// myObject.foo === "bar"
res.send("I am done");
});
EDIT: JSON.stringify() and JSON.parse() will serialize/deserialize JSON. (jQuery makes this much easier, but if you wanna go pure javascript)
Change to var params = "text=" + JSON.stringify({ foo : "bar" });
and
console.dir(JSON.parse(req.body.text));
It worked for me on my local.

Related

Show new html page after post request?

1. Summarize the problem
First I want to describe, how the project should work. I want to build my own little website with html, css, javascript (and expressJS and nodeJS). I´ve also watched a few tutorials about Rest-APIs and how they work. I want to create a login page, where you should enter a password to get to the "main- page".
The problem is, that I´m working with a post-request atfer the user has clicked on a "submit" - button, where the value of a password box will be send to a server to check. After this was executed, I dont know how to show the new html page and how to redirect the user to a new page.
2. Describe what you´ve tried & 3. Show some code
I´ve tried two different things. Here is my beginning of the code in my server.js:
var app = express();
var server = app.listen(3000);
app.use(express.static('website'));
First I wanted to send a file after checking the password in my post request:
app.post('/all', function(req, res) {
if(req.body.password != 'example') {
return
}
res.sendFile('index.html');
});
I found this github issue, where a user has the same problem: https://github.com/expressjs/express/issues/692
But this method doesnt seem to work in a post-request. So I´ve tried another thing. I already knew, that sendFile() works in a get-request (as I mentioned in a github issue), so I´ve made this:
app.get('/all', function(req, res) {
res.sendFile('index.html');
});
app.post('/register', function(req, res) {
if(req.body.password != 'example') {
return
}
res.redirect('/all')
});
For this code example I used the following stack overflow page: How to redirect to another page after serving a post request in Node.js? but it didnt work either.
3. Show some code:
Script in html doc :
function XHTML_POST(path, parms, callback) {
req = new XMLHttpRequest();
var ret = false;
callbackPOST = callback;
req.open("POST", path, true);
req.onload = function () {
if (req.status != 200 && req.status != 1223 && req.status != 0 && req.status != 204) {
if (req.status == 401) { }
else { }
}
else {
callbackPOST = callback;
}
}
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
req.setRequestHeader("Cache-Control", "no-cache");
req.send(parms);
}
function postPass() {
var pass = document.getElementById('pwBox').value; //id of passwordbox
XHTML_POST('/register', 'password=' + pass, callback)
}
function callback() { }
</script>
After clicking on a submit button the postPass() function will be executed. Hopefully you understood my problem and what I´m trying to make. Thanks for reading it.
You can use the html forms :
HTML :
<form method="POST">
<input type="email" name="youremail" placeholder="Email Address" required>
<input type="text" name="yourname" placeholder="Name" required>
<input class="subscribe-button" type="submit" value="Subscribe">
</form>
NodeJs Server :
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, 'login.html'))
})
app.post("/", (req, res) => {
//Your Password Verification
if(true){
res.sendFile(path.join(__dirname, 'index.html'))
}else{
res.sendFile(path.join(__dirname, 'login.html'))
}
})

How to handle ajax post request with node.js and without framworks?

I'm practicing node js and ajax without any frameworks (like jquery, expressJS) by doing a simple app that gives information about a city's weather using openweatherapi.
Here is my code so far:
app.js
const http = require("http");
const fs = require("fs");
const path = require("path");
const { parse } = require('querystring');
const server = http.createServer((req, res)=>{
if(req.url === "/"){
fs.readFile("index.html", "UTF-8", function(err, data){
res.writeHead(200, {"Content-Type": "text/html"});
res.end(data);
});
}else if(req.url === "/public/styles.css"){
var cssPath = path.join(__dirname + req.url);
var cssFileStream = fs.createReadStream(cssPath, "UTF-8");
res.writeHead(200, {"Content-Type": "text/css"});
cssFileStream.pipe(res);
}else if(req.url === "/public/main.js"){
var jsFileStream = fs.createReadStream(`${__dirname}/${req.url}`, "UTF-8");
res.writeHead(200, {"Content-Type": "text/js"});
jsFileStream.pipe(res);
}else if(req.url === "/favicon.ico"){
res.statusCode=204;
res.end();
};
if(req.url ==="/"&&req.method==="POST"){
let body = "";
req.on('data', chunk=>{
body += chunk.toString();
});
req.on("end", ()=>{
parse(body);
});
console.log(body);
};
});
var PORT = process.env.port || 3000;
server.listen(PORT);
console.log(`Server listening on port ${PORT}`);
index.html
<!DOCTYPE html>
<html>
<head>
<title>Weather Application</title>
<link href="./public/styles.css" rel="stylesheet" type="text/css"/>
<script src="./public/main.js"></script>
</head>
<body>
<div class="weather-div">
<h1> Search for weather information of a city</h1>
<form method="post" action="/">
<input class="locationName" id="cityName" name="city" type="text" placeholder="City" required/>
<input class="locationName" id="countryName" name="city" type="text" placeholder="Country"/>
</form>
<button id="submitBtn" type="submit">Search Weather</button>
</div>
<body>
</html>
main.js
function getData(){
var city = document.getElementById('cityName');
var country = document.getElementById('countryName');
if(city.value.length>0){
const apiKey = "APIKey";
const apiUrl = "http://api.openweathermap.org";
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
};
};
xhttp.open("POST", "app.js",true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(`city=${city}&country=${country}`);
};
};
window.onload=function(){
document.getElementById("submitBtn").addEventListener("click", getData, false);
};
So what i want to do is to send the city name of the input using ajax because i tried with a simple form and a submit button, but it keeps on refreshing the page. I don't want it. And I want a receive the data in app.js to parse it and filter its code with a json file of cities and then return it to main.js to send an api call to openweathermap.
Fortunately i know how to do the simple stuff: the parsing and the api call. But all the other stuff i have totally no idea. when i search about it, I only find a solution using jquery or express, but I don't want that, i want pure javascript to get better.
Thank you in advance.
First argument in an event callback is the event object. For a form, to prevent the default browser behavior of refreshing or navigating to the action page, use e.preventDefault().
So the click event that executes callback getData would look like:
function getData(e){ // First argument of an event callback is the event
e.preventDefault(); // Prevent default button type submit behavior
var city = document.getElementById('cityName');
var country = document.getElementById('countryName');
if(city.value.length>0){
const apiKey = "APIKey";
const apiUrl = "http://api.openweathermap.org";
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
};
};
xhttp.open("POST", "app.js",true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(`city=${city}&country=${country}`);
};
};

information from a JavaScript site to the NODE.js server

I have a site in javascript where I get information from a Rest API (JSON)
I would like to make this information available to my server (A node.js that I have created that connects to the database)
It is my first time working with web development; I would like to know how I make the connection between the two?
front end
<!DOCTYPE html>
<head>
<style>
.bodyFrame {
margin: 40px;
}
.headerLabel {
font-weight: bold;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div class="bodyFrame">
<h2 style="text-align:center;">WIDS JSON Retrieval Example</h2>
<button type="button" onclick="makeServiceCall()">Retrieve JSON Data</button>
<br /><br />
<label class="headerLabel">Programs</label>
<ul id="programUL"></ul>
<div>
<script>
function makeServiceCall() {
var url = "http://widsservicedev.yaharasoftware.com/WidsService/JSON/GetPortagePrograms/?apikey=104043F0-9C24-4957-879D-046868973CC4&callback";
$.getJSON(url, function (data) {
//var myArray = [];
//myArray[0] = data;
parseProgramData(data, url);
});
}
function parseProgramData(jsonData, url) {
$("#dataHeader").empty();
$("#dataHeader").append('<b>' + url + '</b>');
var programUL = document.getElementById("programUL");
for (var pgmIndex = 0; pgmIndex < jsonData.Programs.length; pgmIndex++) {
var pgmLi = document.createElement("li");
var program = jsonData.Programs[pgmIndex];
var programInfoRevision = program.ProgramInfoRevisions[0];
var numberTitle = programInfoRevision.ProgramNumber + " " + programInfoRevision.ProgramTitle;
pgmLi.appendChild(document.createTextNode(numberTitle));
programUL.appendChild(pgmLi);
var linebreak = document.createElement("br");
pgmLi.appendChild(linebreak);
var poLabel = document.createElement("label");
poLabel.appendChild(document.createTextNode("Program Outcomes"));
poLabel.classList.add("headerLabel");
pgmLi.appendChild(poLabel);
var pgmOutcomeUL = document.createElement("UL");
pgmLi.appendChild(pgmOutcomeUL);
for (var poIndex = 0; poIndex < program.ProgramOutcomes.length; poIndex++) {
var poLi = document.createElement("li");
poLi.appendChild(document.createTextNode(program.ProgramOutcomes[poIndex].Description));
pgmOutcomeUL.appendChild(poLi);
}
}
}
</script>
</body>
<footer>
</footer>
node.js
var express = require('express');
var app = express();
app.get('/', function (req, res) {
var sql = require("mssql");
// config for your database
/* var config = { user: 'papercut', password: 'Portage.2018', server: 'devsqlcl2:1433', database: 'AgrM6', port: "1433", dialect:",ssql", dialectOptiond:"SQLEXPRESS" };*/
// connect to your database
sql.connect('mssql://xxx:xxxx#xxxx:1433/xxx', function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query('select * from dbo.balance_papercut', function (err, recordset) {
if (err) console.log(err)
// send records as a response
res.send(recordset);
});
});
});
var server = app.listen(5000, function () { console.log('Server is running..'); });
Thank you.
Well to make those data available to the server you basically have to sent a request to the server containing those data. Since you want to sent data to the server you most likely need to use a POST request. There are more informations here about how to send such a request.
On the server side you need to an endpoint listening for a post request. You can find a lot of information about how to do this on the server on google.
A simple way to accomplish connection between frontend and backend is to create api-endpoints. You have already done so with your app.get('/', function (req, res).
You can do a similar one for sending data to the server. The http method used to send data to the server is generally POST. You can read more about the http methods here:
https://restfulapi.net/http-methods/
A good guide I stumbled upon a few weeks ago are this one:
https://codeforgeek.com/2014/09/handle-get-post-request-express-4/
In this example it does exactly what you're trying to accomplish, by sending data from a script in a static html-file to an Express server.

AngularJS: How do I translate this to the 'Angular Way' and using AngularJS

I'm using this form lo do a post request to my node server. Right now it works but I want to translate this to Angular. I've tried ng-file-upload with little success. For some reason the page works perfectly with the plain form but as soon as I try anything fancy with Angular I keep getting 500s from the server.
This is the form that works:
<form action="/auth/upload" method='post' enctype='multipart/form-data'>
<input type="file" name="photo" id="photo" multiple=false>
<button type="submit">Submit</button>
</form>
This is my server side code.
router.post('/upload', upload.single('photo'), function(req, res, next){
var bucketName = '..';
var file = req.file;
var filename = file.originalname;
var ext = _.last(filename.split('.'))
var keyName = uuid.v4() + '.' + ext;
var url = process.env.AWS_URL + bucketName + '/' + keyName;
var params = { Bucket: bucketName, Key: keyName, Body: file.buffer, ACL:'public-read' };
s3.putObject(params, function(err, data) {
if (err){
console.log(err)
}
else{
console.log("Successfully uploaded data to myBucket/myKey");
console.log("The URL is", url);
}
});
res.sendStatus(200);
});
The server works nicely with this form, this is why I'm interested in not changing my backend and find a way to adapt angular to translate what my form is doing right now.

Node.js req.body empty

I am having a hell of a time with this one. I don't know why my node.js response is empty. It comes back {} if I send it through the javascript here, or if I use the Advanced REST client. Here is my code:
client.js
unction ajaxPost(){
var req = new XMLHttpRequest();
var payload = {'Add Item':'Add Item',
'name':document.getElementById('submitForm').elements[0].value,
'reps':document.getElementById('submitForm').elements[1].value,
'weight':document.getElementById('submitForm').elements[2].value,
'date':document.getElementById('submitForm').elements[3].value,
'lbs':document.getElementById('submitForm').elements[4].value
}
payload['test'] = 'value!';
console.log('did this happen?');
console.log(payload['test']);
var url = '/edit';
req.open('POST', url, true);
req.setRequestHeader('Content-Type', 'application/json');
req.addEventListener('load',function(){
if(req.status >= 200 && req.status < 400){
var response = JSON.parse(req.responseText);
console.log('you got a response!')
} else {
console.log("Error in network request: " + req.statusText);
}});
console.log(JSON.stringify(payload));
req.send(JSON.stringify(payload));
event.preventDefault();
}
HTML
<form id = "submitForm">
<input type="text" name="name" id="name" value='test'>Name<br>
<input type="text" name="reps" id="reps" value='10'>Reps<br>
<input type="text" name="weight" id="weight" value='100'>Weight<br>
<input type="text" name="date" id="date" value='1/1/16'>Date<br>
<input type="text" name="lbs" id="lbs" value='1'>Pounds<br>
<input type="submit" onclick = 'ajaxPost()' value="Add Item">
</form>
server
var express = require('express');
var mysql = require('./dbcon.js');
var bodyParser = require('body-parser');
var app = express();
var handlebars = require('express-handlebars').create({defaultLayout:'main2'});
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('port', 3010);
app.post('/edit',function(req,res,next){
//var context = {};
console.log('you posted!');
console.log(req.body);
In my console, I see that the req.body is {}.
I don't know what I am doing wrong. I have tried using httpbin and I can see that the javascript works fine, which means I am probably doing something wrong on the node side, but I cannot figure out what. If I instead use method="submit" on the form, then the post goes through just fine, but it's not what I want to do. What am I doing wrong?? Because advanced REST client also fails, I am guessing it is node?
You are sending json in the request, but you only have middleware setup to handle url encoded requests. Add this to your middleware and json requests should populate in the req.body.
app.use(bodyParser.json());
More info can be found at in the body parser documentation. Specifically you'll notice that the middleware you are using urlencoded states that it only parses urlencoded bodies (this is where Content-Type is used).
You are setting the header to be json
req.setRequestHeader('Content-Type', 'application/json');
and not using bodyParser.json().
Try adding app.use(bodyParser.json());

Categories