Get HTTP request body data using Node.js - node.js

The frontend is index.html:
axios.post('http://localhost:1337/', {
clientId: document.getElementById('clientId').value,
cmd: document.getElementById('cmd').value,
type: document.getElementById('type').value,
amt: document.getElementById('amt').value,
merchantRef: document.getElementById('merchantRef').value,
channel: document.getElementById('channel').value,
successUrl: document.getElementById('successUrl').value,
failureUrl: document.getElementById('failureUrl').value,
webhookUrl: document.getElementById('webhookUrl').value,
goodsName: document.getElementById('goodsName').value
})
.then(function (response) {
var json = response.data;
document.getElementById('sessionId').innerHTML = json['sessionId'];
SpiralPG.init(json['sessionId']);
})
.catch(function (error) {
console.log(error);
});
The backend is server.js:
http.createServer(async function (req, res) {
try {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST');
res.setHeader('Access-Control-Allow-Headers', '*');
const buffers = [];
for await (const chunk of req) {
buffers.push(chunk);
};
const data = Buffer.concat(buffers).toString();
saleSession(res, data);
}
catch (error) {
console.log(error);
}
}).listen(port);
something inside function saleSession(); in the server.js to get the data from frontend(if I hard code in here, there will be no error, but change to input data from frontend, there will be error):
var merchantRef = JSON.parse(data).merchantRef;
let bodyData =
{
'clientId': JSON.parse(data).clientId,
'cmd': JSON.parse(data).cmd,
'type': JSON.parse(data).type,
'amt': JSON.parse(data).amt,
'merchantRef': merchantRef,
'channel': JSON.parse(data).channel,
'successUrl': JSON.parse(data).successUrl,
'failureUrl': JSON.parse(data).failureUrl,
'webhookUrl': JSON.parse(data).webhookUrl,
'goodsName': JSON.parse(data).goodsName
}
I'm just copy the code in https://nodejs.dev/learn/get-http-request-body-data-using-nodejs, which is node.js office website. Why the output is:
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at saleSession (C:\Users\JoeChan\Desktop\my-nodejs2\server.js:41:28)
at Server.<anonymous> (C:\Users\JoeChan\Desktop\my-nodejs2\server.js:104:9)
at processTicksAndRejections (node:internal/process/task_queues:96:5)

Related

"\" in JSON response

So my app gets data from my database but it send a response with " \ "
Express response
[
{
"ID": "account-saassan",
"data": "{\"uuid\":\"saassan\",\"username\":\"sasasasasa\"}"
}
]
Console output:
[
{
ID: 'account-saassan',
data: '{"uid":"saassan","username":"sasasasasa"}'
}
]
Code:
const UserData = new db.table("userdata")
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.get("/list", (request, response) => {
let data = UserData.all()
console.log(data)
response.type('json');
response.json(data)
// I've tried with response.send too. And without response.type
})
app.listen(8080)
Why does it add "" in the response and how do I fix it?
Try to using JSON.stringify
response.json(JSON.stringify(data))
Add please add this :
response.setHeader('Content-Type', 'application/json');

Acessing request body without using Express Nodejs

So I am trying to access the body of a request I am sending. I don't want to incorporate Express for this project. I understand that I essentially have to stream the body in from the incoming request, however it seems that my approach isn't pulling any data from the request. Here is what I have
The request
var query = document.getElementById('search').value;
console.log(query);
axios({
method: 'get',
url: url,
headers: {},
data: {
query: query
}
}).then((response) => {
if(response.status == 200){
console.log(response);
this.tweet = response;
}
}).catch((error) => {
console.log(error);
});
Where I am handling the request
http.createServer((req, res ) => {
//Setting CORS Headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', '*');
if ( req.method === 'OPTIONS' ) {
res.writeHead(200);
res.end();
return;
}
else if(req.url == "/search"){
let body = 'Our Data: ';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
console.log(body);
});
//console.log(data);
callTweetAPI.callTweetAPI(function(response) {
res.write(JSON.stringify(response));
res.end();
});
}
}).listen(port);
The output I expect would be the data I sent in the axios request so 'query', but I end up with blank output. It seems that the request being sent through doesn't have a data block available?

Node/Express API request proxy error using Cloud 9. How do I solve this?

I am working on a simple 'app', and thus, trying to retrieve information from an API (OMDB) but keep getting the following error message:
express deprecated res.send(status, body): Use res.status(status).send(body)
instead app.js:18:10
_http_server.js:193
throw new RangeError(`Invalid status code: ${statusCode}`);
^
RangeError: Invalid status code: 0
at ServerResponse.writeHead (_http_server.js:193:11)
at ServerResponse._implicitHeader (_http_server.js:158:8)
at ServerResponse.OutgoingMessage.end (_http_outgoing.js:585:10)
at ServerResponse.send (/home/ubuntu/workspace/APIs/movieapp/node_modules/express/lib/response.js:211:10)
at ServerResponse.json (/home/ubuntu/workspace/APIs/movieapp/node_modules/express/lib/response.js:256:15)
at ServerResponse.send (/home/ubuntu/workspace/APIs/movieapp/node_modules/express/lib/response.js:158:21)
at Request._callback (/home/ubuntu/workspace/APIs/movieapp/app.js:18:10)
at Request.self.callback (/home/ubuntu/workspace/APIs/node_modules/request/request.js:187:22)
at emitTwo (events.js:87:13)
at Request.emit (events.js:172:7)
I'm on cloud 9, and am just getting my feet wet with regards to NodeJS/Express, so I am a bit lost here. I have tried editing the code as per several suggestions/looking at similar queries but nothing seems to work. The message error message I get on the web page is as follows: ECONNRESET: Request could not be proxied! There was an error proxying the request.
Here's my code:
var express = require("express");
var app = express();
var request = require("request");
app.get("/", function(req, res) {
res.send("Welcome to Our Site");
});
app.get("/movie", function(req, res) {
request('http://www.omdbapi.com/?t=Inception', function (error, response, body) {
if (error) {
res.send('error:', error);
}
else if (Number(response.statusCode) !== 200) {
res.send('statusCode:', response && response.statusCode);
}
else {
res.send('Awards:', JSON.parse(body).Awards);
}
});
});
app.listen(process.env.PORT, process.env.IP, function(){
console.log("Server started!!!");
});
Side note: I tried making the following request and it works:
var request = require('request');
request('http://www.omdbapi.com/?t=Inception', function (error, response, body) {
if (error) {
console.log('error:', error);
}
else if (Number(response.statusCode) !== 200) {
console.log('statusCode:', response && response.statusCode);
}
else {
console.log('Awards:', JSON.parse(body).Awards);
}
});
res.send([body])
Sends the HTTP response.
The body parameter can be a Buffer object, a String, an object, or an Array. For example:
res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
res.status(404).send('Sorry, we cannot find that!');
res.status(500).send({ error: 'something blew up' });
https://expressjs.com/en/api.html#res.send
var express = require("express");
var app = express();
var request = require("request");
app.get("/", function (req, res) {
res.send("Welcome to Our Site");
});
app.get("/movie", function (req, res) {
request('http://www.omdbapi.com/?t=Inception', function (error, response, body) {
if (error) {
res.send({ 'error': error });
}
else if (Number(response.statusCode) !== 200) {
res.send(response).status(response.statusCode)
}
else {
// res.send(JSON.parse(body).Awards);
res.send({ 'Awards': JSON.parse(body).Awards });
}
});
});
app.listen(3000, function () {
console.log("Server started!!!");
});
In the below code you are just doing console, so it will work fine and just print out the strings and the values
var request = require('request');
request('http://www.omdbapi.com/?t=Inception', function (error, response, body) {
if (error) {
console.log('error:', error);
}
else if (Number(response.statusCode) !== 200) {
console.log('statusCode:', response && response.statusCode);
}
else {
console.log('Awards:', JSON.parse(body).Awards);
}
});

Stream Rest API HTTP Response in Node.js & Express

I am creating a Rest API in Node.js and Express. It connects with remote HANA database & execute one query. Now I want to stream HTTP response so that I can send it to browser into chunks, rather than sending it completely since it's a very large data.
I tried something which is giving me no output. I don't know the reason. If I send the complete response to browser using response.send (data), it's working fine. But streaming is now working.
I have added code snippet below.
const express = require("express");
const APP = express();
const HANA_DB = require('hdb');
const BODY_PARSER = require("body-parser");
start();
function start() {
startServer();
initializeExpress();
APP.get("/data", function(request, response) {
var connection = HANA_DB.createClient({
host : "hostname",
port : "port",
user : "username",
password : "password"
});
connection.on('error', function (error) {
console.log("Error in database connection...");
});
connection.connect(function (error) {
if (error) {
console.log("Error in database connection...");
return;
}
var query = "SELECT * FROM TableName";
connection.exec(query, function(error, result) {
if(error) {
response.send("Getting error while fetching result...");
return;
}
//response.send(data);
var datalength = 0;
request.on('data', function(chunk) {
datalength += chunk.length;
console.log("DATA EVENT: " + datalength);
response.send(datalength);
})
.on('end', function() {
console.log("END EVENT: " + datalength);
response.send(datalength);
});
});
});
});
};
function initializeExpress() {
APP.all('/*', function(request, response, next) {
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Headers", "X-Requested-With");
response.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
response.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
APP.use(BODY_PARSER.json());
APP.use(BODY_PARSER.urlencoded({ extended: true }));
};
function startServer(config) {
var server = APP.listen("8081", function(error) {
if(error) {
console.log("Unable to connect to 127.0.0.1:8081");
return;
}
console.log("Server is listening at - 127.0.0.1:8081");
});
};
I think the logic you are using is wrong for the streaming the data.
Use res.write instead of res.send and you also have to read streaming data from your database instead of one time connection.exec
I am giving you an example code where you will get some idea about streaming data in Expressjs.
var http = require( 'http' );
http.createServer( function ( req, res ) {
res.writeHead( 200, {
'Content-Type': 'text/plain; charset=utf-8',
'Transfer-Encoding': 'chunked',
'X-Content-Type-Options': 'nosniff'
} );
res.write( 'Beginning\n' );
var count = 10;
var io = setInterval( function () {
res.write( 'Doing ' + count.toString() + '\n' );
count--;
if ( count === 0 ) {
res.end( 'Finished\n' );
clearInterval( io );
}
}, 1000 );
} ).listen( 8000 );
The problem is here request.on('data',. request refers to the browser request.
You cannot use streaming with .exec(), because the callback function of exec is called with the rows as parameters.
To use streaming, use the .execute() method, which passes a resultset to the callback function.
I never used hdb, so I cannot give the code to use.

Getting User information from identity provider and Azure EasyAPI

I'm trying to create an Azure EasyAPI to get some user information from the identity provider (microsoft) in my app. However, I'm getting an error from all of the examples I've found online and none of the answers I've found on stackoverflow have helped.
Error:
Azure Log:
: Application has thrown an uncaught exception and is terminated:
SyntaxError: Unexpected end of input
at Object.parse (native)
at IncomingMessage.<anonymous> (D:\home\site\wwwroot\node_modules\azure-mobile-apps\src\auth\getIdentity.js:35:55)
at emitNone (events.js:72:20)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:903:12)
at doNTCallback2 (node.js:439:9)
at process._tickCallback (node.js:353:17)
Code:
module.exports = {
"get": function (request, response, next) {
request.azureMobile.user.getIdentity('microsoftaccount').then(function (data) {
var accessToken = data.microsoftaccount.access_token;
var url = 'https://apis.live.net/v5.0/me/?method=GET&access_token=' + accessToken;
var requestCallback = function (err, resp, body) {
if (err || resp.statusCode !== 200) {
console.error('Error sending data to the provider: ', err);
response.send(statusCodes.INTERNAL_SERVER_ERROR, body);
} else {
try {
var userData = JSON.parse(body);
response.send(200, userData);
} catch (ex) {
console.error('Error parsing response from the provider API: ', ex);
response.send(statusCodes.INTERNAL_SERVER_ERROR, ex);
}
}
var req = require('request');
var reqOptions = {
uri: url,
headers: { Accept: "application/json" }
};
req(reqOptions, requestCallback);
};
}).catch(function (error) {
response.status(500).send(JSON.stringify(error));
});
//...
}};
Thanks for the help.
In API Documentation of Azure Mobile Apps for Node.js, it indicates that the getIdentity method accepts the name of the authentication provider as a parameter and returns a promise that yields the identity information on success.
So your code should look like:
module.exports = {
"get": function (req, res, next) {
req.azureMobile.user.getIdentity('microsoftaccount').then(function (data) {
var accessToken = data.microsoftaccount.access_token;
//...
}).catch(function (error) {
res.status(500).send(JSON.stringify(error));
});
}
}
Another option to get the user info is to call /.auth/me endpoint.
var https = require('https');
module.exports = {
"get": function (request, response, next) {
var token = request.azureMobile.user.token;
var options = {
hostname: '<yourappname>.azurewebsites.net',
port: 443,
path: '/.auth/me',
method: 'GET',
headers: {
'x-zumo-auth': token
}
};
var req = https.request(options, (res) => {
var str = '';
res.on('data', (d) => {
str += d;
});
res.on('end', function () {
console.log(str);
response.status(200).type('application/json').json(str);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();
}
}

Resources