JavaScript/Nodejs : ajax POST request not passing object to backend - javascript

I'm attempting to post a JSON object to my server, but when I console log req.body it shows an empty object. Here's my code:
var submitRecipe = () => {
let recipe = {alias: null, description: null, instructions: null};
recipe.alias = document.getElementById('alias').value;
recipe.description = document.getElementById('description').value;
recipe.instruction = document.getElementById('instructions').value;
postRequest("/createrecipe", recipe, (xhr) => {
console.log("Hello!" + JSON.parse(xhr.responseText));
})
};
var postRequest = (url, data, callback = undefined) => {
xhr.onreadystatechange = () => {
//Call a function when the state changes.
if(xhr.readyState == 4 && xhr.status == 200) {
console.log("testing");
return callback(200 , xhr.responseText);
}else{
return callback(400, xhr.responseText);
}
}
xhr.open('POST', url)
xhr.send(data);
}
Node
createRecipe = function(req, res){
console.log(req.body);
}
I'm using express to transfer the server information, and I am using bodyParser.json(). From there, I just call the controller with the following:
express
var express = require("express");
var bodyParser = require("body-parser");
var server = express();
var recipeController = require("./controllers/recipeController");
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true}));
server.post("/createrecipe", recipeController.createRecipe);
The createRecipe function just console logs the information, but as stated before, req.body is an empty object. All tips are appreciated.

XHR expects your data to be encoded or packed in whatever way you expect it to be send unlike other library wrappers like jQuery or Angular Ajax wrapper functions.
Alsobody-parsermiddleware was not identifying the Content-type and was not activating for the required request.
Simply JSON.stringify your json data
data = JSON.stringify(data);
and add the application/json MIME type as xhr's content-type header.
xhr.setRequestHeader("content-type", "application/json");
Also, If you want to use url-encoded do the encoding of your data before attaching and add the corresponding header content type.
My full test code (for reference purposes):
Server (testServer.js):
var express = require("express");
var bodyParser = require("body-parser");
var server = express();
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true}));
server.post("/createrecipe", function(req, res){
console.log(req.body);
var resp = {server: "hello world", dataReceived: req.body};
res.json(resp);
});
server.get("/", function(req, res){
res.sendFile(__dirname + "/testClient.html");
})
server.listen(3000, function(){
console.log("Server running");
})
Client (testClient.html):
<input type="text" id="alias" value="a">
<input type="text" id="description" value="b">
<input type="text" id="instructions" value="c">
<button onclick="submitRecipe()"> TEST</button>
<script>
var submitRecipe = () => {
let recipe = {alias: null, description: null, instructions: null};
recipe.alias = document.getElementById('alias').value;
recipe.description = document.getElementById('description').value;
recipe.instructions = document.getElementById('instructions').value;
postRequest("/createrecipe", recipe, (status, xhr) => {
var data = (JSON.parse(xhr.responseText));
console.log(data.dataReceived);
})
};
var postRequest = (url, dataObj, callback = undefined) => {
//--------------Added line--------------------
var data = JSON.stringify(dataObj);
//--------------Added line--------------------
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
//Call a function when the state changes.
if(xhr.readyState == 4 && xhr.status == 200) {
return callback(200 , xhr);
}else if(xhr.status == 400){
return callback(400, xhr);
}
}
xhr.open('POST', url)
//--------------Added line--------------------
xhr.setRequestHeader("content-type", "application/json");
//--------------Added line--------------------
xhr.send(data);
}
</script>

Related

getting empty object while sending formData [duplicate]

Here is my frontend JS. As a side note, FormData.append() does not work, so I have to set its properties explicitly. #data is an object with input name: value properties.
function http(data) {
const httpData = new FormData();
for (let prop in data) {
httpData[prop] = data[prop];
}
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4) {
const status = this.status;
const data = this.responseText;
}
};
xhttp.open('POST', '/api/login');
xhttp.setRequestHeader('Content-Type', 'x-www-form-urlencoded');
xhttp.send(httpData);
}
And on the server side
app.use(express.urlencoded({
extended: true
}));
express ready to parse form data, and in the /routes/api.js ( I am using express router )
router.post('/login', (req, res, next) => {
console.log(req.body);
res.end();
});
I got req.body as an {}
Where did I fuck up ?
Here is the working code, courtesy of #Quentin, frontend
function http(data) {
const httpData = new FormData();
for (let prop in data) {
httpData.append(prop, data[prop]);
}
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4) {
const status = this.status;
const data = this.responseText;
}
};
xhttp.open('POST', '/api/login');
xhttp.send(httpData);
}
and backend in /routes/api.js
const formidable = require('formidable');
router.post('/login', (req, res, next) => {
const form = formidable({ multiples: true });
form.parse(req, (err, fields, files) => {
console.log(fields);
res.end();
});
});
You have three problems.
append() does work. It just doesn't store the data in a way that shows up with console.log. Assigning arbitrary properties doesn't work.
You need to send the correct Content-Type header. This is multipart/form-data with a mandatory boundary parameter that you have no way of knowing. Don't try to set the Content-Type header manually. XMLHttpRequest will generate it automatically from the FormData object.
You need a body parser for Express that supports multipart/form-data. The built-in one does not. The documentation for it on npm suggests 4 alternatives.

Express post not receive JSON data [close]

I have this problem because I am sending data via JavaScript using XMLHttpRequest but not receiving it in node.js express post method. I don't know what I'm doing wrong.
My script - funcion form execute on window load
function form() {
const btn = document.getElementById("save-data");
let currentPage = window.location.href.split("/").at(-1);
function sendData(data) {
const XHR = new XMLHttpRequest();
XHR.open("POST", window.location.href);
XHR.setRequestHeader("Content-Type", "application/json");
console.log(data); // I get right data
XHR.send(data);
}
btn.addEventListener("click", () => {
switch (currentPage) {
case "settings":
const prefix = document.getElementById("prefix").value;
let buttonState = document.getElementById("module-state");
if (buttonState.hasAttribute("enable")) {
buttonState = "enable";
} else {
buttonState = "disable";
}
sendData({
prefix: prefix,
buttonState: buttonState,
announcements: {
giveawayChannelID: 123,
updateChannelID: 123,
},
});
}
});
}
My Node.js code
router.post('/:id/settings', (req, res) => {
console.log(req.body) // {}
})
Pleas help.
You need to install body-parser package by NPM, and require it in your code
Try
npm i body-parser
Then in your main node script, require it
const bodyParser = require('body-parser');
after that, you should set it as a middleware for express
app.use(bodyParser.json()); //Handles JSON requests
app.use(bodyParser.urlencoded({ extended: false })); //Handles normal post requests
after these steps, you can access values like req.body.value

How to fix AJAX request on browser side unable to send data to local server?

I am trying to send data to local server using XMLHTTPServer. However, I am unable to receive it on the server side.
I tried printing out the object that was passed through but the body of request received by server is empty even though I am passing the data after using JSON.stringify(data). The server uses the data passed to talk to mongodb hosted on AWS.
BROWSER SIDE:
var cardID = 1233456789;
var data = JSON.stringify({ "Card ID": cardID });
console.log("data = " + data);
var url = `http://${serverIP}/findUser`;
var xhr = createCORSRequest("POST", url);
if (!xhr) {
alert("CORS not supported");
return;
}
xhr.onload = function() {
if (this.status == 200 && this.readyState == 4) {
userData = JSON.parse(this.responseText);
if (userData == "") {
console.log("ERROR LOADING USERS");
alert(
"USER NOT REGISTERED. Contact Michael Hofmann to Register yourself"
);
} else {
//window.location.replace('https://ha6017.github.io/link_table.html?cardid='+cardID);
console.log("userData=" + userData);
}
}
};
xhr.onerror = function() {
alert("Woops, there was an error making the request.");
};
console.log(xhr);
xhr.send(data);
SERVER SIDE:
app.post("/findUser", (req, res) => {
//console.log('req.body = ' + JSON.stringify(req.body));
var card_ID = req.body["Card ID"];
//console.log('finding user with card ID: ' + card_ID);
var que = {'Card ID': card_ID};
dbUtil.findExt("User_info", que, dbres => {
sendCORS(res, 200, dbres);
});
});
I expect the data from browser to be passed onto server side. The request body can see the card_ID as 1233456789 in the req.body
I was not able to replicate your code, because I don't know what your createCORSRequest() method is doing.
I got it working like this.
test.html
var cardID = 1233456789;
var data = JSON.stringify({ cardid: cardID });
console.log('data = ' + data);
var url = `http://localhost:3005/findUser`;
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (this.status == 200 && this.readyState==4) {
userData = JSON.parse(this.responseText);
if (userData == '') {
console.log('ERROR LOADING USERS');
alert('USER NOT REGISTERED. Contact Michael Hofmann to Register yourself');
} else {
//window.location.replace('https://ha6017.github.io/link_table.html?cardid='+cardID);
console.log('userData=' + userData);
}
}
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
console.log(xhr);
xhr.send(data);
server.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser')
var cors = require('cors')
// use CORS
app.use(cors())
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
extended: true
}));
// parse application/json
app.use(bodyParser.json())
app.post("/findUser", (req, res) => {
console.log('req.body = ' + JSON.stringify(req.body));
//console.log('finding user with card ID: ' + card_ID);
var que = { 'Card ID': card_ID };
/* dbUtil.findExt("User_info", que, dbres => {
sendCORS(res, 200, dbres);
});*/
});
app.listen(3005, function () {
console.log('Example app listening on port 3005!');
});

How to render object from REST response

I want to render to the ui / print to console log some object value from GET response.
I'm using Node JS for my server side and HTML + JS for my client side.
Because my goal is to render data and the request type is cross domain I can't use "fetch" function.
My only alternative to execute it is to send it by "JSONP" dataType.
Actually, the request is sent and the response receives by callback as well, but my code is print "null" to the console and not the response data.
When I've tried to used JSON.parse() it received a "parseerror".
The expected result it's to get only the image tag value (2.0.90) and to print this inside the console log / render it to the UI.
async function uiChecking() {
let index;
const hostsDock = [qa + dockers];
let lengthVal = hostsDock.length;
for (let hostIndxD = 0; hostIndxD < lengthVal; hostIndxD++) {
index = hostIndxD;
let url = hostsDock[hostIndxD];
$.ajax({
url: url,
dataType: 'jsonp',
}).done( function(data) {
console.log("A " + data);
});
}
}
**Server.js **
var express = require('express');
var cors = require('cors');
var app = express();
var path = require("path");
var fetch = require('fetch-cookie')(require('node-fetch'));
var btoa = require('btoa');
var http = require('http');
var corsOptionsDelegate = function (req, callback) {
var corsOptions;
if (whitelist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
}else{
corsOptions = { origin: false } // disable CORS for this request
}
callback(null, data , corsOptions) // callback expects two parameters: error and options
};
app.engine('.html', require('ejs').__express);
app.set('views', __dirname + '/view');
app.set('view engine', 'html');
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res){
res.render('index');
res.render('logo');
res.writeHead(200, {'Content-Type': 'application/json'});
});
// app.get('/products/:id', cors(corsOptionsDelegate), function (req, res, next) {
// res.json({msg: 'This is CORS-enabled for a whitelisted domain.'})
// });
app.get('/data/:id', function (req, res, next) {
var opts = {
host: config.alertService.host,
port: config.alertService.port,
method: 'GET',
path: '/DataService/rest/receiveData/' + req.params.id
}
var reqGet = http.request(opts, function (dataResponse) {
var responseString = '';
dataResponse.on('data', function (data) {
responseString += data;
});
var response = {x:[],y:[],z:[],t:[]};
dataResponse.on('end', function () {
var responseObject = JSON.parse(responseString);
var accs = responseObject.data.listPCS;
for(var i in accs){
response.x.push(accs[i].accX);
response.z.push(accs[i].accY);
response.y.push(accs[i].accZ);
response.t.push(accs[i].timestamp);
}
res.jsonp(response);
});
});
reqGet.end();
reqGet.on('error', function (e) {
console.error(e);
});
});
if (app.settings.env === 'production') {
app.error(function(err, req, res) {
res.render('new404.html', {
status: 500,
locals: {
error: error
}
});
});
}
app.listen(8033, function () {
console.log('CORS-enabled web server listening on port 8033')
});
You need to iterate through the response to return the result e.g..
$.each(data, function(index) {
console.log(data[index].ui);
console.log(data[index].id); console.log(data[index].Name);
});

how can i send html form data to node.js server by making ajax call?

I want to send form data to node.js server using Ajax and I am fallowing the below approach to send data.
I am not getting how receive it in node.js server program I am not using express framework for node.js
client.HTML
<script>
function myFunction() {
var region = document.getElementById("region").value;
var os = document.getElementById("os").value;
var data = {};
data.region = region;
data.os = os;
$.ajax({
type: 'post',
datatype: 'jsonp',
data: JSON.stringify(data),
contentType: 'application/json',
url: 'http://127.0.0.1:8083/', //node.js server is running
success: function(data) {
alert("success");
}
});
</script>
<form>
<select id="region" name="region" class="region"></select>
<select id="os" name="os" class="os"></select>
<input type="button" value="search" class="fil_search" onclick="myFunction()"/>
</form>
server.js
var http = require('http');
var fs = require('fs');
var url = require('url');
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert')
var ObjectId = require('mongodb').ObjectID;
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var result1=[];
var result2=[];
var result3=[];
var result4=[];
var result5=[];
var result6=[];
var result7=[];
var i=0;
var region;
var os;
app.use(bodyParser.urlencoded({ extended: true }));
MongoClient.connect("mongodb://192.168.1.22:27017/test", function(err, db) {
if(err) { return console.dir(err); }
else {
app.get('/',function(req, res) {
var url_parts = url.parse(req.url, true);
var url_parsed = url.parse(req.url, true);
"i want data here from ajax to perform"
console.log("connected");
var instance = db.collection('instance');
var region = db.collection('region');
region.findOne(({$and: [{"region_name": region_name},{"os_type": os}]}), function(err, result){
if(err){
throw(err);
}
else{
console.log(region);
var newr = result.inst_name;
instance.find({ "inst_id": { "$in": newr } }).toArray(function(err, resultn){
if(err){
throw(err);
}
else{
var len=resultn.length;
console.log(resultn);
console.log(len);
for(var i=0;i<len;i++)
{
result1[i]=resultn[i].inst_type;
result2[i]=resultn[i].vcpu;
result3[i]=resultn[i].memory_gib;
result4[i]=resultn[i].storage;
result5[i]=resultn[i].phy_processor;
result6[i]=resultn[i].clock_spd;
result7[i]=resultn[i].netwk_pef;
}
var wstream = fs.createWriteStream('myOutput.txt');
wstream.write(result1.toString()+"~"+result2.toString());
//var str = "Hi man"
res.writeHead(200, {'Content-Type':'text/html'});
//res.end(url_parsed.query.callback+'("'+resultn.toString()+'")');
res.end(url_parsed.query.callback+'("'+result1.toString()+"~"+result2.toString()+"~"
+result3.toString()+"~"+result4.toString()+"~"+result5.toString()+"~"+result6.toString()
+"~"+result7.toString()+'")');
}
});
}
});
}).listen(process.env.PORT || 8083);
}
});
I am not getting how to receive data in node.js server program and after receiving data I want process on that data and send back processed data to same HTML page.
If you have app.use(bodyParser.urlencoded({ extended: true })); in your server.js file then using bodyParser you can retrieve data from ajax as given below:
app.post('/', function(req, res) { //your ajax should also post to url: '/'
var region = req.body.region,
os = req.body.os;
// ...
});

Categories

Resources