NodeJS / Express res.download not sending file - node.js

Here is the server code:
router.get("/download", (req, res) => {
console.log("downloading file...");
const file = `${__dirname}/../downloads/dummy.txt`;
res.download(file);
});
and here is the client-side JQuery:
const downloadSoftware = () => {
$.ajax({
type: "GET",
url: "/download",
success: function(res) {
console.log("success");
},
error: function(res) {
console.log("error");
}
});
};
HTML:
<a id="downloadParser" onclick="downloadSoftware()">
Download Parser
</a>
My problem is when I click on the tag, nothing happens in my browser when a file should be downloading.
EDIT:
when I click the tag i get this in the console for NodeJS:
GET /download 304 1.751 ms - -

Related

postman request works with no problem but when executing my test.js file i get a 404

I have an issue with a request to an API that I try to build but I get a 404 in node js when executing my test.js file.
Error:
HEADERS: {"date":"Sun, 18 Oct 2020 17:23:18 GMT","server":"Apache","scs-request-id":"c4b2baae-64da-423e-9356-7533f9489b28","content-type":"application/json","content-length":"178","connection":"close"}
BODY: {"status":"404","code":"INVALID_REQUEST_RESOURCE","message":"The requested resource does not exist. Verify that the resource URI is correctly spelled.","error":"invalid_request"}
this is how my test.js file looks like:
var https = require('https');
const options = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: { 'grant_type': 'client_credentials' },
auth: 'user:pass',
method: 'POST',
port: 443
};
const requ = https.request('https://consent.swisscom.com/o/oauth2/token', options, (resp) => {
console.log(`STATUS: ${resp.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(resp.headers)}`);
resp.setEncoding('utf8');
resp.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
resp.on('end', () => {
console.log('No more data in response.');
});
});
requ.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
requ.end();
when I execute the test.js file by running node test.js I get the above-mentioned error.
if I do a postman request there is no problem.
it seems to me like node.js wants to perform a GET instead of a POST as I instruct it to.
can you advise?
thanks

React-native node.js showing Error: Multipart: Boundary not found while uploading image using react-native-image-picker

While Uploading image , It is showing Error: Multipart: Boundary not found on node js server console
here is my react native code
const createFormData = async (photo, body) => {
const data = new FormData();
console.log("photoooooooooooo",photo.fileName);
data.append("photo", {
name: photo.fileName,
type: photo.type,
uri:
Platform.OS === "android" ? photo.uri : photo.uri.replace("file://", "")
});
Object.keys(body).forEach(key => {
data.append(key, body[key]);
});
console.log("datatyeeeeeeeeeeeeee",data);
return data;
};
const chooseFile = async() => {
var options = {
title: 'Select Image',
customButtons: [
{ name: 'customOptionKey', title: 'Choose Photo from Custom Option' },
],
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.showImagePicker(options, response => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
alert(response.customButton);
} else {
let source = response;
// You can also display the image using data:
// let source = { uri: 'data:image/jpeg;base64,' + response.data };
setfilePath(source);
// postImage(source);
handleUploadPhoto(source);
}
});
};
const handleUploadPhoto = async (filePath) => {
fetch("http://192.168.43.118:3000/updateImageprofile2", {
method: "POST",
body: createFormData(filePath, { userId: "123"}),
headers: {
Accept: 'application/json',
// 'Content-Type': 'image/jpeg',
'Content-Type': 'multipart/form-data',
// 'Content-Type': 'application/octet-stream'
},
})
.then(response => response.json())
.then(response => {
console.log("upload succes", response);
alert("Upload success!");
// this.setState({ photo: null });
})
.catch(error => {
console.log("upload error", error);
alert("Upload failed!");
});
};
and backend node js
router.post("/updateImageprofile2", upload.single('photo'), (req, res,next) => {
console.log("I am in");
console.log('files', req.files)
console.log('file', req.file)
console.log('body', req.body)
res.status(200).json({
message: 'success!',
})
});
but on the node js console it is showing
Error: Multipart: Boundary not found
at new Multipart (C:\react\udemy_react\start\emb\auth_server2\node_modules\busboy\lib\types\multipart.js:58:11)
at Multipart (C:\react\udemy_react\start\emb\auth_server2\node_modules\busboy\lib\types\multipart.js:26:12)
at Busboy.parseHeaders (C:\react\udemy_react\start\emb\auth_server2\node_modules\busboy\lib\main.js:71:22)
at new Busboy (C:\react\udemy_react\start\emb\auth_server2\node_modules\busboy\lib\main.js:22:10)
at multerMiddleware (C:\react\udemy_react\start\emb\auth_server2\node_modules\multer\lib\make-middleware.js:33:16)
at Layer.handle [as handle_request] (C:\react\udemy_react\start\emb\auth_server2\node_modules\express\lib\router\layer.js:95:5)
So there is a button which I click then choosefile function calls and after choosing files it goes to handlephoto function where the body part formdata create or append the image data into body then send the data to node js server where I am trying to upload image on upload folder but it is not happening. Please help me , I am trying it since morning and its evening
TL;DR Try omitting the Content-Type header. If it's not set, the browser will set it for you and it'll also configure the boundary.
The referenced boundary is the boundary you must provide alongside multipart/form-data. In your example it has not been provided.
When sending a request with content of type multipart/form-data you must provide the boundary value.
POST /test HTTP/1.1
Host: foo.example
Content-Type: multipart/form-data;boundary="boundary"
--boundary
Content-Disposition: form-data; name="field1"
value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"
value2
--boundary--
MDN: HTTP POST Method
In your post request, you are providing this content type without a boundary, which results in an error when the content is parsed.
However, often the easiest solution is to omit this header entirely. In this case the browser will configure this header for you--it'll also manage the boundary for you.

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();

Render EJS - Node JS

I would like to update my view after an ajax call, rendering compiled ejs from the server.
These two previous questions seem to achieve this but I cannot update my view
Can't Render EJS Template on Client
How to generate content on ejs with jquery after ajax call to express server
So from what I understand I should compile my ejs file (partial) on the server.
fixtures.ejs
<% fixtures.forEach((fixture) => { %>
<h2><%= fixture.home_team %> vs <%= fixture.away_team %></h2>
<% }) %>
index.js
app.post('/league_fixtures', async function (req, res) {
try {
var league_name = req.body.league_name;
const fixtures = await leagueFixtures(league_name);
//compile view
fs.readFile('./views/fixtures.ejs', "utf-8", function(err, template) {
fixture_template = ejs.compile(template, { client: true });
var html = fixture_template({fixtures: fixtures});
console.log(html);
// This logs out my HTML with fixtures so I am almost there
// <h2>Club Africain vs Al-Faisaly Amman</h2>
// <h2>Al Nejmeh vs ASAC Concorde</h2>
});
res.json({fixtures: fixtures });
} catch (err) {
res.status(500).send({ error: 'Something failed!' })
}
});
Ajax
$("a.league-name").on("click", function (e) {
e.preventDefault();
var league_name = $(this).text().trim();
$.ajax({
url: '/league_fixtures',
type: 'POST',
dataType: "json",
data: { league_name: league_name },
success: function(fixtures){
// How do i get HTML from server into here ?
$('#panel_' + league_name).html(fixtures);
},
error: function(jqXHR, textStatus, err){
alert('text status '+textStatus+', err '+err)
}
})
});
});
I don't get any errors when I fire the ajax request but I also do not get any data or HTML updated in my div.
What am I doing wrong?
So I finally got a working solution:
index.js
app.post('/league_fixtures', async function (req, res) {
try {
const league_name = req.body.league_name;
const fixtures = await leagueFixtures(league_name);
const file = await readFile('./views/fixtures.ejs');
var fixture_template = ejs.compile(file, { client: true });
const html = fixture_template({fixtures: fixtures});
res.send({ html: html });
} catch (err) {
res.status(500).send({ error: 'Something failed!' })
}
});
ajax call
$.ajax({
url: '/league_fixtures',
type: 'POST',
dataType: "json",
cache: true,
data: { league_name: league_name },
success: function(fixtures){
var html = fixtures['html'];
$('#panel_' + league_name).html(html);
},
error: function(jqXHR, textStatus, err){
alert('text status '+textStatus+', err '+err)
}
})

Resources