I had a problem in req.body at server as i received req.body as {} empty, here is the code at service
addEmployeeCollection(addArray: EmployeeSchema) {
let url: string = Constants.DOMAIN + Constants.CREATE_EMPLOYEE_ROUTE;
console.log('addArray at employee service', addArray)
var body = addArray;
return this._httpService.post(url, body).map(res => res.json()).catch(this._errorHandler);
}
this._httpService.post(url, body) will go to the interceptor, there the http.post method returned, here is the interceptor code,
post(url: string, body: Object, options ? : RequestOptionsArgs): Observable < Response > {
this.headers.append('Content-Type', 'application/json');
let token = localStorage.getItem('realtoken');
console.log('http token', token);
if (typeof url === 'string') {
if (!options) {
options = {
headers: this.headers
};
}
options.headers.set('Authorization', ` ${token}`);
}
return super.post(url, body, options).catch(this.catchAuthError(this));
}
now here the request payload at headers contains the information,
The response from the server side is
{"__v":0,"_id":"58ba4969ed69821fd6f7e573"}// details of employee is not saved
here the server side code
var mongoose = require('mongoose');
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
//schema-models
var employeeCollection = require('../../model/employee.model.js');
router.post('/new', function(req, res) {
var employee_data = req.body;
console.log('req.body=====> ', req.body)
var addcontent = new employeeCollection(employee_data);
console.log('addcontent--->', addcontent);
addcontent.save(function(err, data) {
if (err) {
res.send(err);
} else {
console.log('data', data);
res.json(data);
}
});
});
module.exports = router;
At terminal, req.body=====> {}, the employee details are sent correctly in the request, but at server side am getting as empty req.body
As a beginner to this concepts,i could not figure out where i am getting wrong, please help me out
Related
I have a server running Express, and a client written in JS.
Using the following code on the client:
document.getElementById("continue").addEventListener("click", function() {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
if(username != "" && password != "") {
const data = {
username, password
};
console.log(JSON.stringify(data));
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
};
fetch(urllogin, options).then(response => {
console.log(response.body);
});
}
And the following code on the server:
let port = 9000;
var express = require("express");
var fs = require("fs");
var https = require("https");
var app = express();
app.use(express.json())
app.use((req, res, next) => {
res.append('Access-Control-Allow-Origin', ['*']);
res.append('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.append('Access-Control-Allow-Headers', 'Content-Type');
next();
});
app.post("/login", (req, res) => {
console.log(req.body);
response = {
body:'hello'
};
res.json(JSON.stringify(response));
});
https
.createServer(
{
key: fs.readFileSync("server.key"),
cert: fs.readFileSync("server.cert"),
},
app
)
.listen(port, function () {
console.log(`Example app listening on port ${port}! Go to https://localhost:${port}/`);
});
I successfully receive the JSON object on the server, but on the client, I get:
{"username":"ok","password":"m"} script.js:20:21
ReadableStream { locked: false }
locked: false
<prototype>: ReadableStreamPrototype { cancel: cancel(), getReader: getReader(), pipeTo: pipeTo(), … }
script.js:29:25
Logged in the console (posted just a part of it).
Why does this happen, and how can I send data as a response to a POST request?
Thank you!
i had a proplem with making two js files one to be put in 'website' directory and the other outside it and when i add a post request it adds a new item to the array from the server side js file and itried it alot and it didnt work so ..
thats My ServerSide Code
/* Empty JS object to act as endpoint for all routes */
projectData = {};
/* Express to run server and routes */
const express = require('express');
/* Start up an instance of app */
const app = express();
/* Dependencies */
const bodyParser = require('body-parser')
/* Middleware*/
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors());
/* Initialize the main project folder*/
app.use(express.static('website'));
const port = 3000;
/* Spin up the server*/
const server = app.listen(port, listening);
function listening(){
// console.log(server);
console.log(`running on localhost: ${port}`);
};
// GET route
app.post('/add', function (req, res) {
let data = req.body;
console.log(data);
});
// POST an animal
const data = []
app.post('/animal', addAnimal)
function addAnimal (req,res){
data.push(req.body);
console.log(data);
}
and That Is My ClientSide Code
/* Function to POST data */
const postData = async ( url = '', data = {})=>{
console.log(data)
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
const newData = await response.json();
console.log(newData);
return newData
}catch(error) {
console.log("error", error);
// appropriately handle the error
}
}
// TODO-Call Function
postData('/addAnimal', {animal:'Tiger'});
postData('/addAnimal', {animal:'Lion'});
when i run the code inside the vs code editor it displays "{ animal: 'lion' }
{ animal: 'Tiger' }"
But it never console log the data
you forget to send the respone
must the route callback have a res endpoint
function addAnimal (req,res){
data.push(req.body);
console.log(data);
// add res end point
res.json({msg : 'added'})
}
//here too
app.post('/add', function (req, res) {
let data = req.body;
console.log(data);
res.end('hello world')
});
Your route is /add or /animal not /addAnimal
postData('/add', {animal:'Tiger'});
in your ServerSide this function should display a log
app.post('/add', function (req, res) {
let data = req.body;
console.log(data);
});
You can't console.log the data in your try / catch because you don't return any response in your server side. But first try log data in your server side controller for confirm the good serverSide execution, and return your response.
How to encode a request body using HMAC sha 256 and base64.
The request object that i receives from xero webhook.
HEADER:
"x-xero-signature" : HASH_VALUE
PAYLOAD:
{
"events": [],
"lastEventSequence": 0,
"firstEventSequence": 0,
"entropy": "S0m3r4Nd0mt3xt"
}
The note from xero documentation says "If the payload is hashed using HMACSHA256 with your webhook signing key and base64 encoded, it should match the signature in the header. This is a correctly signed payload. If the signature does not match the hashed payload it is an incorrectly signed payload."
And I followed this example : https://devblog.xero.com/using-xero-webhooks-with-node-express-hapi-examples-7c607b423379
const express = require("express");
const router = express.Router();
const base64 = require('base-64');
const crypto = require('crypto')
const bodyParser = require('body-parser')
const xero_webhook_key = '00fRRlJBYiYN4ZGjmTtG+g/pulyb1Eru68YYL3PFoLsa78dadfQtGrOMuISuVBHxpXeEYo0Yy1Gc+hHMhDkSI/EEcgtrA==';
let options = {
type: 'application/json'
};
let itrBodyParser = bodyParser.raw(options);
router.post("/", itrBodyParser, async (req, res, next) =>{
// console.log('::::WebhookPost:::');
const reSign = req.headers['x-xero-signature'];
console.log(req.headers['x-xero-signature']);
console.log('::::::::');
console.log(req.body);
console.log("Body: "+JSON.stringify(req.body))
console.log(req.body.toString());
console.log("Xero Signature: "+ reSign);
console.log('Server key::::',xero_webhook_key);
// Create our HMAC hash of the body, using our webhooks key
let hmac = crypto.createHmac("sha256", xero_webhook_key).update(req.body.toString()).digest('base64');
console.log("Resp Signature: ",hmac)
if (req.headers['x-xero-signature'] == hmac) {
res.statusCode = 200
} else {
res.statusCode = 401
}
console.log("Response Code: "+res.statusCode)
return res.send();
});
Hey I recently did a video on implementing webhooks with Xero, let me know if this gets you unstuck. I found that trying to pass itrBodyParser on the route the way you have wasn't working for me so I switched it with an app.use statement on my specific webhooks endpoint. If you prefer a written guide over video, here's the blog post
I solved it using this solution.! I was using express framework and the request were not getting as raw request also .toString of didn't worked as mentioned in xero documentation.
const server = http.createServer(async (req, resp) => {
try {
console.log(`::::Webhook::: ${webhookPort}`);
console.log("::::x-xero-signature:::");
console.log(req.headers["x-xero-signature"]);
console.log(`--------------------------------------`);
if (req.method === "POST") {
if(req.headers["x-xero-signature"]){
const rData = await new Promise((resolve, reject) => {
return collectRequestData(req, (result) => {
console.log(result);
let hmac = crypto
.createHmac("sha256", xero_webhook_key)
.update(result)
.digest("base64");
console.log("Resp Signature: ", hmac);
return resolve({
hmac,result
});
});
});
console.log(">>Resp Signature: ", rData);
console.log('>>x-xero-signature:::',req.headers["x-xero-signature"]);
if(rData.result){
const result = JSON.parse(rData.result);
console.log('result:::',result);
for(let { resourceId } of result.events) {
console.log('::INVOICE ID = ',resourceId);
getInvoiceData(resourceId);
}
}
if(rData.hmac == req.headers["x-xero-signature"] ){
console.log('::YES');
resp.statusCode = 200;
}else{
console.log('::NO');
resp.statusCode = 401;
}
}
resp.end();
}
console.log("::::Webhookgetsssss:::");
resp.message = 'Get API'
resp.end();
} catch (error) {
resp.statusCode = 200;
resp.end();
}
});
server.listen(webhookPort);
function collectRequestData(request, callback) {
let body = "";
request.on("data", (chunk) => {
body += chunk.toString();
});
request.on("end", () => {
callback(body);
});
}
I'm really struggling with an example project for an online course and I think there's alot I'm doing wrong with the code. The example code I'm given in these example projects frequently don't work and I need to add/change/remove parts all over the place. I think I'm making alot of wrong changes. The first problem I'm having is that I get this error when I go to /addAnimal:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
The second problem I'm having is that when I go to /fakeAnimalData I see the data in the body of the HTML but not in the console as a javascript object. Then when I go to /addAnimal and submit the form I get the fav data in the body of the HTML but not in the console. The ultimate goal is to get the data from /fakeAnimalData AND the data (animal and fact) from the form in /addAnimal to show up in the console as a single javascript object with all three elements (animal, fact, fav). This is the code I have so far:
server.js:
/* Empty JS object to act as endpoint for all routes */
projectData = {};
/* Express to run server and routes */
const express = require('express');
/* Start up an instance of app */
const app = express();
/* Dependencies */
const bodyParser = require('body-parser')
/* Middleware*/
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors());
/* Initialize the main project folder*/
app.use(express.static('project1'));
const port = 8000;
/* Spin up the server*/
const server = app.listen(port, listening);
function listening(){
// console.log(server);
console.log(`running on localhost: ${port}`);
};
// GET route
const animalData = [];
const fakeData = {animal: "lion", fact: "a lion's roar can be heard five miles away"};
app.get('/fakeAnimalData', getFakeData);
function getFakeData(req, res) {
res.send(fakeData)
};
app.get('/all', getData);
function getData(req, res){
res.send(animalData)
console.log(animalData)
}
// function sendData (request, response) {
// response.send(projectData);
// };
// POST route
app.post('/add', callBack);
function callBack(req,res){
res.send('POST received');
}
// POST an animal
const data = [];
// TODO-Call Function
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(addAnimal)
function addAnimal(req, res){
newEntry = {
animal: req.body.animal,
facts: req.body.fact,
fav: req.body.fav
}
data.push(req.body);
res.status(200).send(req.body);
animalData.push(newEntry)
res.send(animalData)
console.log(animalData)
};
app.js:
function performActuion(e){
const fav = document.getElementById('fav').value;
const getAnimal = async (url) =>{
const res = await fetch(url);
try {
const data = await res.json();
console.log(data)
return data;
} catch(error) {
console.log()
}
};
/* Function to POST data */
const postData = async ( url = '', data = {})=>{
console.log(data);
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
const newData = await response.json();
console.log(newData);
// console.log(newData);
return newData.json()
console.log(await response.json());
return await response.json()
}catch(error) {
console.log("error", error);
// appropriately handle the error
};
};
// TODO-Call Function
getAnimal('/fakeAnimalData')
.then(async function(data){
console.log(data)
let res = await postData('/addAnimal', (animal: data.animal, fact: "lions are fun", fav: fav));;
console.log(res);
})();
Any guidence at all would be much, much appreciated.
Thanks,
Mike
function addAnimal(req, res){
newEntry = {
animal: req.body.animal,
facts: req.body.fact,
fav: req.body.fav
}
data.push(req.body);
// >>>>res.status(200).send(req.body);
animalData.push(newEntry)
res.send(animalData)
console.log(animalData)
};
You can't modify the res object after it has been already been sent, thus the error
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);
});