how to perform operations with json string from axios? - node.js

Background
I am passing variable from my frontend HTML file using axios
var idToken1 = result.getIdToken();
axios({
method: 'post',
url: '/trial',
data: idToken1,
headers: {'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
in my app.js under route getting this as output,here all the values are present in key and key values is empty. so i think i need a way to parse those keys first
{
'{"payload":{"cognito:username":"jatin","exp":1620965984,"iat":1620962384,"email":"xxxx#gmail.com"}}': ''
}
i want to extract "email":"xxxx#gmail.com"
update: in app.js i am already using express native parser app.use(express.json()); app.use(express.urlencoded({ extended: true }));`

A parser is required if you want to get the http body as object:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));
Then you can use req.body to get the http body sent by your html web:
app.post('/trial', function(req, res) {
var email = req.body.payload.email;
//etc
});

The problem was with axios. axios needed object to be send as json object.
var idToken1 = result.getIdToken();
the following code results in proper JSON object in my backend
axios({
method: 'post',
url: '/trial',
data: { idToken: idToken1 },
headers: { 'Content-Type': 'application/json' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});

The Problem cause is 'Content-Type'
is should be 'application/json'
axios({
method: 'post',
url: '/trial',
data: idToken1,
headers: { 'Content-Type': 'application/json' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});

Related

How do I send JSON data to node.js server using fetch?

I have a node.js back-end server. Front-end is running on Angular 10.
I want to pass data from front-end to back-end using fetch
Front-end code :
testmariadb($event: MouseEvent) {
return fetch('/api/customQuery', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
sqlQuery: 'SELECT * FROM software'
})
})
}
Back-end code
app.post('/api/customQuery', async (req, res) => {
let test = req.body['sqlQuery']
console.log(test)
})
I get this error :
let test = req.body['sqlQuery']
^
TypeError: Cannot read properties of undefined (reading 'sqlQuery')
at /home/erwan/Documents/GitHub/serverAltertManager/index.js:90:22
What I'm doing wrong ?
Are using the middleware properly
const express = require('express');
const app = express();
app.use(express.json());
testmariadb() {
fetch('APIURL', {
method: 'POST',
headers: {'Content-Type': 'application/json; charset=UTF-8'},
body: JSON.stringify({
key: 'Value'
})
}).then((result)=>{
return result
})
}

How to compress json to get it with `bodyParser.json`

I want to send to my server a compressed json.
I prefer to compress the data in browser.(explainer) and get it to bodyParser.json middleware.
client side function something like this:
export function compressGzip(input) {
const stream = new Response(input).body.pipeThrough(
new CompressionStream('gzip')
)
return new Response(stream)
}
my request in react.js:
return fetch(url, {
headers: {
'Content-Type':'application/json',
'content-encoding': 'gzip'
},
method: 'POST',
body: bodyContent
}).then(res => res.blob())
node.js:
app.use(
bodyParser.json({
limit: "10mb"
})
);
What is the way to do the compression according to this data and does it make sense?
Thank in advance!
I've done this with zlib, but not GZIP.
Firstly, I have this client-side function....
function compressBody(body) {
return new Promise( function( resolve, reject ) {
zlib.deflate(body, (err, buffer) => {
if(err){
console.log("Error Zipping");
reject(err);
}
console.log("Zipped");
resolve(buffer);
});
});
}
To call function....
let compressedBody = await compressBody(JSON.stringify(body));
I can then assign this compressedBody var to the webervice call...
var promise = fetch(ServiceUrl, {method: 'POST', headers:headers, body:compressedBody}).then((result) => result.json() );
You will then need to change the server-side code to accept a compressed body. I used Express and did the following...
var BodyParser = require('body-parser');
require('body-parser-zlib')(BodyParser);
var app = express();
// Other code....
app.use(BodyParser.zlib()); // support json encoded bodies
app.use(BodyParser.json({"inflate": true})); // support json encoded bodies
Got it with blob, it works perfectly :)
The code:
client side:
export function compressGzip(input) {
const stream = new Response(input).body.pipeThrough(
new CompressionStream('gzip')
)
return new Response(stream).blob()
}
const bodyContent = await compressGzip(JSON.stringify({data: data})
return fetch(url, {
headers: {
'Content-Type':'application/json',
'content-encoding': 'gzip'
},
method: 'POST',
body: bodyContent
}).then(res => res.blob())
server side - node.js:
app.use(
bodyParser.json({
limit: "10mb"
})
);

nodejs request post large json fail

I am trying to post large json to a http server(a grafana server actually):
here is my code:
const http = require('http')
const request = require('request')
const fs = require('fs')
const opts = {
hostname: 'myip',
port: 3000,
path: '/api/dashboards/uid/KPEiIQVWk',
method: 'GET',
timeout: 5000,
headers : {
'Authorization' : 'Bearer ********************************************',
'Accept' : 'application/json',
'Content-Type' : 'application/json'
}
}
const req = http.request(opts, res => {
console.log(`Fetch: statusCode: ${res.statusCode}`)
var origin = ''
res.on('data', d => {
origin += d
})
res.on('end', function(){
dash = JSON.parse(origin)
dash.dashboard.panels.forEach(p => {
if(p.id == 26){
fs.readFile(__dirname + '/grafana/pm/branch-graph.html','utf-8', function(err, newPanel){
if(err){
console.log(err)
}
p.content = newPanel
const fresh = JSON.stringify(dash)
const updateOptions = {
uri: 'http://myip:3000/api/dashboards/db',
method: 'post',
headers : {
'Authorization' : 'Bearer *************************',
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Content-length' : fresh.length
},
json: fresh
}
fs.writeFile('tmp.json', fresh, function(err){
if(err){
console.error(err)
}
})
request(updateOptions, function(error, response, body){
console.log(`update: statusCode=${response.statusCode}`)
console.log(`update: ${body}`)
})
})
}
})
})
})
req.on('error', error => {
console.error(error)
})
req.on('timeout', () => {
req.abort()
})
req.end()
as you can see, I first fetch a grafana dashboard's source, then make some udpate, then post it back to grafana server. but always get 400 error. The strange thing is that if I dump the json to a file and use curl to post, it will work.
curl -vH "Authorization: Bearer $TOKEN" -H "Expect:" -d #tmp.json -H "Content-Type:application/json" http://myip:3000/api/dashboards/db
the whole json is about 40000+ bytes. any hint on this? I am not very famillar with nodejs. I am just trying to write some CI scripts.
First, I don't think it's necessary to use both the http and request modules. http is a module built into nodejs, and request is an npm package.
I recommend you use the npm request package because it's easier. You can read its documentation here: https://www.npmjs.com/package/request#http-authentication
Second, the options you're passing to the request module is not formatted correctly, I think this is why it is not working. With your current code, I would console.log('POST error', error); to print out the error. The correct options for the request module is proposed below.
const options = {
url: 'https://myip:3000/api/dashboards/db',
body: fresh, // the json from the fs.read callback
auth: {
'bearer': 'bearerToken'
},
json: true // from docs: If json is true, then body must be a JSON-serializable object.
}
request.post(
options,
(err, httpResponse, body) => {
console.log(err, body);
});

Why i am getting unable to open document error or blank pdf in opening a pdf on client side?

I am hitting a get api in react similar to http://www.orimi.com/pdf-test.pdf which needs some secret information which is available only at middleware written in node. I want to open the pdf on client side(browser). So I am hitting the proxy get api which will hit the middleware and middleware will hit the backend server, but I am getting unable to open document and blank pdf. Can anyone tell me what is wrong with this code?
fetch(pdfApiMiddlewareUrl, {
method: "GET",
headers: {
"Content-Type": "application/pdf",
'Content-Disposition': 'inline; filename=your_file_name'
},
responseType : 'blob'
})
.then(res => res.blob())
.then(response => {
var blobUrl = URL.createObjectURL(response);
window.open(blobUrl);
})
.catch(error => {
console.log("HEREEEEEEEE");
console.log(error);
});
MIDDLEWARE CODE:
var urlEndPointsToHit = decodeURIComponent(req.query.urlToHit);
var url = urlEndPointsToHit+'?secret='+secretInfo;
var options;
options = {
url: url,
method: 'GET',
headers: {
'Content-type': 'application/pdf'
},
};
if(options) {
options.qs = req.query || {};
}
request(options, function(err, resp, body) {
req.locals = body;
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Cache-Control', 'no-cache');
next();
});

Node Express Get request passing a custom header

I am trying to make a get request equivalent to this jQuery:
$.ajax({
headers: { 'X-Auth-Token': 'YOUR_API_KEY' },
url: 'http://api.football-data.org/v2/competitions/BL1/standings',
dataType: 'json',
type: 'GET',
}).done(function(response) {
console.log(response);
});
However, I haven't figured out how to do it using nodejs - express. This code is from an api routes module attached to the main app.
The request seems to work, collecting the data but does not end. Also, I cannot see the custom header in the request when inspecting from the browser.
app.get('/api/:league', function(req, res, next) {
var apiKey = process.env.API_KEY;
let url = 'api.football-data.org';
var options = {
host: url,
method: 'GET',
path: 'v2/competitions/BL1/standings',
headers: {
'X-Auth-Token': apiKey
}
};
let data = "";
var getReq = http.request(options,function(resp){
console.log("Connected");
resp.on("data", chunk => {
data += chunk;
});
resp.on("end", () => {
console.log("data collected");
});
});
getReq.on("error", (err) => console.log("OOPS!", err));
getReq.end(JSON.stringify(data));
})
Link to project
Try using request-promise npm package.https://www.npmjs.com/package/request-promise
var rp = require(request-promise);
const baseUrl = 'api.football-data.org/v2/competitions/BL1/standings';
const apiKey = process.env.API_KEY;
var options = {
method: 'GET',
uri: baseUrl,
headers: {
'X-Auth-Token': apiKey
},
json: true
};
rp(options)
.then(function (response) {
console.log(response)
}
);
jQuery ajax function does not have headers option. You can read about this function on official doc http://api.jquery.com/jquery.ajax/ . They custom request header by beforeSend function way:
$.ajax({
beforeSend: function (request) {
request.setRequestHeader("X-Auth-Token", 'YOUR_API_KEY');
},
url: 'http://api.football-data.org/v2/competitions/BL1/standings',
dataType: 'json',
type: 'GET',
}).done(function (response) {
console.log(response);
});
With http node lib, you can flow this example
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
// TODO: send data to client
// res.status(200).json(JSON.stringify(body.toString()))
console.log(body.toString());
});
});
req.end();

Resources