How to know when file downloading is finished? - node.js

I need to get an user download his file and remove it after response get finished:
app.get('/download/:file', function (req, res) {
var filePath = '/files/' + req.param('file');
res.download(file);
fs.unlink(filePath);
});
In the code above fs.unlink could invoked early than res.download will get finished.

Use the callback in the download api:
res.download(filePath, req.param('file'), function(err){
//CHECK FOR ERROR
fs.unlink(filePath);
});

res.download(filePath, req.param('file'), function(err){
//CHECK FOR ERROR
fs.unlink(filePath);
});

Related

How to respond without reloading my current page?

I have Express API which used to upload file to the files directory. Whenever I call my API res.send redirecting to a new page. How can I perform this API with reloading my current page?
app.post('/upload', function(req, res) {
let sampleFile;
let uploadPath;
if (Object.keys(req.files).length == 0) {
res.status(400).send('No files were uploaded.');
return;
}
console.log('req.files >>>', req.files); // eslint-disable-line
sampleFile = req.files.sampleFile;
console.log('lusu', sampleFile); // eslint-disable-line
uploadPath = __dirname + '/uploads/' + sampleFile.name;
sampleFile.mv(uploadPath, function(err) {
if (err) {
return res.status(500).send(err);
}
res.send('File uploaded to ' + uploadPath);
});
});
First of all, I would like to recommend multer package for file upload in node js.
instead of res.send(), try res.status(200).json({message:"successfully uploaded"})
try debugging at front end, suppose you have a function for file upload like below,
function fileUpload(){
http.post('url',{headers:headers}).then(res){
// Try to handle the response here. Do not write anything that reloads the page.
}
}

Node Express "favicon.ico" not found error

I'm trying to download a photo through a URL passed as a query string using Express, but every time I try to use it, I get Error: Invalid URI "favicon.ico" Is there a way I can get my browser to stop requesting a favicon? For downloading images, I'm using the image-downloader package (NPM page)
Code:
app.get('/:url', (req, res) => {
let url = req.params.url;
const options = {
url: url,
dest: /path'
};
download.image(options)
.then(({ filename, image }) => {
console.log('File saved to ', filename);
})
.catch((err) => {
console.log(err);
});
res.send("Done");
});
It's probably easiest to just make a route for favicon.ico in your server.
app.get('/favico.ico', (req, res) => {
res.sendStatus(404);
});
Of course, you could actually send a valid icon too if you wanted, but this will at least keep your Express server from showing an error.
FYI, this has nothing to do with the image-downloader. This has to do with the browser requesting a favico.ico icon that it uses to show in the URL bar (and some other places in the browser UI). If your server returns a 404 for favicon.ico, the browser will use a generic icon in its UI.
If you want to make yourself a simple favico.ico, you can go here and it will help you generate one and then you can change the above route to:
app.get('/favico.ico', (req, res) => {
res.sendFile("myfavico.ico");
});
Try using another package like request module. I believe it got this type of things handled.
var fs = require('fs'),
request = require('request');
var download = function(uri, filename, callback){
request.head(uri, function(err, res, body){
console.log('content-type:', res.headers['content-type']);
console.log('content-length:', res.headers['content-length']);
request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
});
};
download('https://www.google.com/images/srpr/logo3w.png', 'google.png', function(){
console.log('done');
});

nodejs multer file upload, path contains double slashes

I am working on image upload via nodejs and multer module and this is the code im using:
app.post('/upload', upload.single('file'), function(req, res, next) {
var tmp_path = req.file.path,
target_path = __dirname + '/public/uploads/' + req.file.originalname,
src = fs.createReadStream(tmp_path),
dest = fs.createWriteStream(target_path);
src.pipe(dest);
fs.unlink(tmp_path); //deleting the tmp_path
src.on('end', function() {
res.json({
success: true,
file: '/uploads/' + req.file.originalname
});
});
src.on('error', function(err) {
console.log('err', err);
res.json({
success: false
});
});
});
The problem is that sometimes (it occures randomly) error callback is triggered, with this contents:
So it looks like additional slashes are added to the path which causes script not to find temp location and returns error, maybe someone encountered this problem and can help ;)
You can use the following code in order to get rid of this error...
try:- path.replace("\\","/");
This will definitely solve your problem.
Try running the unlink after success message is sent, pipe is asynchronous so might be executing after the delete.
src.on('end', function() {
res.json({
success: true,
file: '/uploads/' + req.file.originalname
});
fs.unlink(tmp_path)
});

Create folder before upload in express js

How can I create a folder (if the folder does not exist yet) before the image will be uploaded? I always get error ENOENT.
When I try this code:
module.exports = function(router){
router.post('/result', directory.tmp, uploader.single, function(req,res){
//some data manipulation here
});
}
//directory.js
module.exports.tmp = function(req, res, next){
mkdirp('./tmp/' + moment().format('MM-DD-YY') + '/' + moment().format('HH'), function (err) {
if (err) console.error(err)
console.log("==================================");
console.log("tmp folder created");
console.log("==================================");
});
next();
};
Though I used directory.tmp first so it will create a folder if it is not existing, I think uploader.single is executed first that is why I got that error. After receiving the error, then that's the time my app created the folder. So in other words, the file uploaded was not saved. How to fix this so it will create the folder first, then upload the file. Btw, I am using mkdirp and multer.
I would suggest you to do the next(); inside the callback of mkdirp.
Because like you did, why it creates the folder it calls next and goes further and the folder is not yet created. This is why you should wait for folder creation first.
module.exports.tmp = function(req, res, next){
mkdirp('./tmp/' + moment().format('MM-DD-YY') + '/' + moment().format('HH'), function (err) {
if (err) console.error(err)
console.log("==================================");
console.log("tmp folder created");
console.log("==================================");
next();
});
};

How to stop upload and redirect in busboy if mime type is invalid?

I am fairly new to Node.js, and I am using Express and Busboy-Connect to create a simple file upload form, for wav files only.
Here is what I am trying to do :
- start the upload
- if the mimetype is not wav, redirect to an error page
- else : write the file on the server and redirect back.
If the mimetype is valid, everything works fine, but if it isn't I cannot redirect and the browser is just hanging and eventually times out.
My understanding of it is that the browser doesn't want to redirect because it is waiting for the upload to finish, but how can I cancel the upload then within my js code ?
I could work around the issue and write the file then delete it if it's not the right mimetype, but I think it's a bit stupid to do that, I'd rather find a way to trigger an event that will stop it and redirect immediately.
Here is (a snippet of) my app code :
app.get('/', function (req, res) {
res.render(__dirname + '/public/index.ejs', {error: 0});
});
app.get('/error', function (req, res) {
res.render(__dirname + '/public/index.ejs', {error: 1});
});
app.post('/upload', function (req, res) {
var timestamp = new Date().getTime().toString();
//console.log(timestamp);
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
if ("audio/wav" != mimetype)
{
console.log("invalid mimetype"); // that prints ok
// req.busboy.end(); // I tried that but it doesn't work
res.redirect('/error');
}
else
{
console.log("Uploading: " + mimetype);
fstream = fs.createWriteStream(__dirname + '/tmp/' + timestamp + filename);
file.pipe(fstream);
fstream.on('close', function () {
res.redirect('back');
});
}
});
});
Can anyone point me in the right direction?
Thank you for your help !
Alright I found it in the docs of npm, if you think anyone could be interested in finding this answer from a google search you can leave it resolved, otherwise feel free to close/remove this post.
Basically there is a function on the filestream that need to be called to unblock busboy, so all I had to do to make it work is to add
file.resume();
before redirecting to the error page.

Resources