NodeJS express/request: piping a POST request with body parsing issue - javascript

I'm trying to pipe a request handling by a remote server, along with the following line:
Unfortunately pipe doesn't work well with post body, could you suggest how can I solve this issue?
self.downloadPriceLists = function (req, res, next) {
const options = {
url: `http://${env.MAILER_HOST}:${env.MAILER_PORT}/getpricelist/`,
method: 'POST',
json: true, // <--Very important!!!
headers: req.headers,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
"Access-Control-Allow-Origin": "*",
},
body: {
userID: req.user.id,
exportAsOf: req.body.exportAsOf,
activationDate: req.body.activationDate,
},
};
console.log("options:", options);
// remoteResponse :: res
// remoteBody :: body
const myReq = request.post(options, function (error, remoteResponse, remoteBody) {
res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
remoteResponse.headers.hasOwnProperty('content-disposition') && res.setHeader('Content-disposition', remoteResponse.headers['content-disposition']);
remoteResponse.headers.hasOwnProperty('content-type') && res.setHeader('Content-type', remoteResponse.headers['content-type']);
if (error) {
console.error('request fail:', error);
return res.status(500).end('Error');
}
console.log('submit successful:', remoteResponse.headers);
res.pipe(remoteBody);
});
// Handle errors
myReq.on('error', function (err) {
console.log("++++++++++++sendReq Handle errors:", err);
res.status(500).end("Error:" + err);
});
};

Should you not be piping streams and not scalar data?
res.pipe(remoteBody); does look right to me, if anything, res.pipe(remoteResponse); seems more right.
Have you considered just writing the response of the inner request to the outer one without piping? Like so res.json(remoteBody); ?

Related

How to get front-end data in the backend using vanilla Node Js

I know it's possible to get data sent by the user in the back-end using Express.js which is:
router.get("/pathName", async function(req, res){
count = req.body;
})
But how to do this in vanilla (pure) Node.js itself?
Here's an example of a simple server.
const http = require('http');
http
.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'text/html',
});
switch (req.url) {
// http://localhost:8080/
case '/':
res.write('<h1>Home</h1>');
break;
// http://localhost:8080/page
case '/page':
res.write('<h1>Page</h1>');
break;
}
res.end();
})
.listen(8080);
Also, here's an example (probably incomplete in terms of all edge cases...) of getting JSON data from a request payload:
const http = require("http");
// server that only supports POST /count
// expects JSON data to be passed like { "count": 100 }
// must have application/json content type header and POST method
http
.createServer(async (req, res) => {
// ensure method is content type json, POST, and /count
if (
req.headers["content-type"] != "application/json" ||
req.url !== "/count" ||
req.method !== "POST"
) {
res.writeHead(404, {
"Content-Type": "application/json",
});
res.write(JSON.stringify({ message: "Unsupported route" }));
res.end();
}
// try to read body
let body;
try {
body = await readBody(req);
} catch (err) {
res.writeHead(400, {
"Content-Type": "application/json",
});
res.write(JSON.stringify({ message: err.message }));
res.end();
}
// try to parse body
let parsedBody;
try {
parsedBody = JSON.parse(body);
} catch (err) {
res.writeHead(400, {
"Content-Type": "application/json",
});
res.write(JSON.stringify({ message: err.message }));
res.end();
}
// make sure count property is present in parsed body
if (typeof parsedBody.count === "undefined") {
res.writeHead(400, {
"Content-Type": "application/json",
});
res.write(JSON.stringify({ message: err.message }));
res.end();
}
// create response
res.writeHead(200, {
"Content-Type": "application/json",
});
res.write(JSON.stringify({ message: "Got " + parsedBody.count }));
res.end();
})
.listen(8080);
function readBody(req) {
return new Promise((res, rej) => {
let body = "";
req.on("data", (data) => {
body += data;
});
req.on("end", () => {
res(body);
});
req.on("error", (err) => {
rej(err);
});
});
}
Cool to see how it works for learning. But if you're using it for a project, I'd highly recommend Express or another framework/lib as you'll find it will get quite painful to try to consider all various cases you will need. Frameworks like Express are quite light anyway.

Can not download file while sending request from one node.js server to another

I am facing some issue while downloading file using node.js. I have scenario like my angular component is sending the file request. in my first node server I am doing the token validation and then redirecting to another node server where actually the execution happens. I am explaining my code below.
service.ts:
submitAndDownloadFile(formdata : any ){
const token = localStorage.getItem('token')
let headers = new HttpHeaders({
Authorization: 'Basic ' + token
})
const cecID = localStorage.getItem('cec');
const AppUrl = `${environment.nodeJsBaseUrl}:${environment.hostingNodeJsContainerPort}/convert-test-cases/${cecID}`;
return this.httpClient.post(AppUrl, formdata, { responseType: 'blob', observe : 'response', headers : headers});
}
Here I am sending the request to my first node.js server which code has given below.
app.js(first:port-8000):
router.post('/convert-test-cases/:id', middleware.auth, (req, res) => {
try{
let postRequestOptions = {
url: '',
method: 'POST',
json: true,
headers: {},
body: {},
};
postRequestOptions.url = 'http:localhost:9000/convert-test-cases';
postRequestOptions.headers = {
'Content-Type': 'application/json',
};
postRequestOptions.body = req.body;
request(postRequestOptions, async (error, response, pathList) => {
if(error) {
console.log('error', error);
}else{
res.send(pathList);
}
})
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here I am doing the token validation using middleware.auth and sending same request to another node.js file which code is explained below.
app.js:(second-port-9000):
router.post('/convert-test-cases', async (req, res) => {
try{
let response = await ctcCtrl.convertTestCase(req.body, req.files);
if(response.status == 'success'){
res.set('Access-Control-Expose-Headers','*, Content-Disposition');
return res.download(response.fileName,response.fileName);
}else{
return res.send(response);
}
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here only I am doing some execution and downloading the file. If I am connecting angular to node-9000 its working fine but my requirement is first I have to connect to port-8000 to some token validation and after that I have to send same req.body and re.file to app.js which is running in 9000 using request module. As per my code its not working at all.

Can't Post Files using Request or Axios in node js

I have to take data from my form in my front end code and upload the data to another server using API calls, which I am unable to do right now. I have tried numerous ways and tricks mentioned over the internet to solve the problem faced while uploading a file in NodeJs using Request and Axios but none of them are working for just this particular case and I don't know why.
Here is the code in my client-side if we use Axios:
app.post('/job/addjob', upload.any(), (req, res) => {
console.log(req.files[0].path);
var form = new formData();
form.append('Title', req.body.Title);
// form.append('Services', JSON.stringify(req.body.Services));
form.append('Startdate', req.body.Startdate);
form.append('NoOfPositions', req.body.NoOfPositions);
form.append('EndDate', req.body.EndDate);
form.append('Experience', req.body.Experience);
form.append('Rate', req.body.Rate);
form.append('Location', req.body.Location);
form.append('Description', req.body.Description);
// form.append('Questions', JSON.stringify(req.body.Questions));
form.append('Dresscode', fs.createReadStream(req.files[0].path));
axios({
method: 'post',
url: 'http://13.127.239.92:3000/job/addjob',
data: form,
headers: {'Content-Type': 'multipart/form-data', 'Authorization': req.session.verifiedToken}
}).then(function (response) {
console.log(response.data);
res.redirect('/provider');
})
.catch(function (err) {
//handle error
console.log(err);
res.redirect('/profile/getProfile');
});
});
for which the error that I face is
Error Uploading Image.
And here is the code in my client-side if we use Request:
app.post('/job/addjob', upload.any(), (req, res) => {
console.log(req.files);
var options = {
'method': 'POST',
'url': 'http://13.127.239.92:3000/job/addJob',
'headers': {
'Content-Type': 'multipart/form-data',
'Authorization': req.session.verifiedToken
},
formData: {
'Title': req.body.Title,
// form.append('Services', JSON.stringify(req.body.Services));
'Startdate': req.body.Startdate,
'NoOfPositions': req.body.NoOfPositions,
'EndDate': req.body.EndDate,
'Experience': req.body.Experience,
'Rate': req.body.Rate,
'Location': req.body.Location,
'Description': req.body.Description,
// form.append('Questions', JSON.stringify(req.body.Questions));
'Dresscode1': fs.createReadStream(req.files[0].path),
}
};
request(options, function (error, response) {
if (error) { console.log(error) }
else {
console.log(response.data);
res.redirect('/provider');
}
});
});
for which the error that I face is:
{ Error: socket hang up
at createHangUpError (_http_client.js:323:15)
at Socket.socketOnEnd (_http_client.js:426:23)
at Socket.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1145:12)
at process._tickCallback (internal/process/next_tick.js:63:19) code: 'ECONNRESET' }
This is the fraction of code from the server-side which might come in handy understanding my problem:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'dresscodes/')
},
filename: function (req, file, cb) {
let uuid=v4();
cb(null, uuid +"."+mime.getExtension(file.mimetype))
pp= uuid +"."+mime.getExtension(file.mimetype);
}
});
let upload = multer({ storage: storage }).any();
upload(req,res,function(err) {
if(err) {
console.log(err);
return res.end("Error uploading image.");
} else{
var fullUrl = req.protocol + '://' + req.get('host') ;
Now to the worst part, I can only make changes to my client-side code and not to the server-side code

How do I send a request from One Nodejs application to another using an IP address?

I have 2 Nodejs Server running. One of the server just has a post route:
app.post("/",(req,res)=>{
console.log(`Someone sent a post request`)
})
This server is running on localhost:9000. How do I fire the post route from a different Nodejs Server?
You could try something similar to this:
var request = require("request");
app.post("/", (req, res) => {
var options = {
method: 'POST',
url: 'http://localhost:9000/employee',
headers: { 'Content-Type': 'application/json' },
body: { id: 1 },
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
// Process the body and return the response.
return res.send(body);
});
});
Additional link

difference between api call and on postman

I was using Azure Speech rest api. And i tried it on post man with a .wav file and it successfully return the result. However, when i call api from my node.js code. It always return Unsupported Audio Format even though i give the same audio file. Can anyone tell me what's the difference of them? Or what did Postman do to make it work?
Below is how i call speech api by node.js.
'use strict';
const request = require('request');
const subscriptionKey = 'MYSUBSCRIPTIONKEY';
const uriBase = 'https://westus.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US';
const options = {
uri: uriBase,
body: 'speech.wav',
headers: {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key' : subscriptionKey,
'Transfer-Encoding': 'chunked',
'Expect': '100-continue',
'Content-type':'audio/wav; codec=audio/pcm; samplerate=16000'
}
};
request.post(options, (error, response, body) => {
if (error) {
console.log('Error: ', error);
return;
}
let jsonResponse = JSON.stringify(JSON.parse(body), null, ' ');
console.log('JSON Response\n');
console.log(jsonResponse);
});
You can try this
fs.readFile('/path/to/my/audiofile.wav', function (err, data) {
if (err) throw err;
var options = {
host: 'https://westus.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US',
method: 'POST',
headers: { 'Content-Type': 'audio/wav' }
};
var req = http.request(options, function(res) {
// Handle a successful response here...
});
req.on('error', function(e) {
// Handle an error response here...
});
// Write the audio data in the request body.
req.write(data);
req.end();
});

Categories

Resources