res.download crashing the browser - node.js

Im trying to send a file on the server to the browser as a download. res.download is cashing the browser.
Any ideas?
Code
var filename = path.basename(userPathZip);
var mimetype = mime.lookup(userPathZip);
res.setHeader('Content-disposition', 'attachment; filename=test.zip');
res.setHeader('Content-type', mimetype);
var filestream = fsextra.createReadStream(userPathZip);
filestream.pipe(res);
in the network tab in chrome the response is 24mb which is the size of the file so im not sure whats goin on here

var filename = path.basename(userPathZip);
var mimetype = mime.lookup(userPathZip);
res.setHeader('Content-disposition', 'attachment; filename=test.zip');
res.setHeader('Content-type', mimetype);
var filestream = fsextra.createReadStream(userPathZip);
filestream.pipe(res);
it is res.pipe(filestream);

What would be the best was to serve files to admin only? Don't want the files making it to a public folder

Related

nodejs sending file to client hangs until server is killed

I am trying to send a csv file to the client.
When I do this, the download begins, but hangs on "starting...." and says it is transmitting at 0B/s.
When I kill the server, the file is transmitted and is all there.
What's causing this?
app.get('/weather_log.csv', function(req, res){
console.log('sending weather log')
filePath = 'weather_log.csv'
var file = fs.readFileSync(filePath, 'binary');
console.log(typeof(file))
res.setHeader('Content-Length', fs.statSync(filePath));
res.setHeader('Content-Type', 'text/csv');
res.setHeader('Content-Disposition', "attachment;filename=" + filePath);
res.write(file, 'binary');
res.end();
})
My guess is that res.end() is not firing or that the client doesn't realise that the file transfer is not complete for some other reason.
As per a0js, the answer was to use res.download(filePath).

How to download image from node server sending image filename in HTTP post request from Angular 2

I want to download an image from node server when sending post request for image file name.But I couldn't get either save dialog box or direct download.I have a folder uploads from which I want to read the image and download.I am trying the code pasted over here.Please help me with a good solution.
router.post('/download', urlencodedParser, function(req, res) {
var img = path.resolve('uploads/' + req.body.file);
var filename = path.basename(img);
var mimetype = mime.lookup(img);
console.log(filename);
console.log(mimetype);
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type', mimetype);
var filestream = fs.createReadStream(img);
filestream.pipe(res);
res.on('finish', function(){
console.log("Download complete");
});
})

NodeJS - Serve file with throttled speed

I'm quite new to NodeJS and trying different stuff.
What I was able to do is to download a file going using the following code:
app.get('/download', function(req, res){
var file = 'public/songs/myfile.mp3';
var filename = path.basename(file);
var mimetype = mime.lookup(file);
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type', mimetype);
res.setHeader('Content-Length', file.length);
var filestream = fs.createReadStream(file);
filestream.pipe(res);
});
This works well, now what I'm trying to achive is see if it's possible to throttle the download speed. Like if someone tries to download the file it will download at max 1 Mbps (for example).
I've tried to use this code: https://gist.github.com/4poc/1454516
When I load the page it seems to load indefinetly, but I think that the problem is
filestream.pipe(limitStream);
Since that no response is given.
How can I implement what I would like to do? Or how I can fix the code I tried to use?
The req and res objects are streams, so you can pipe on the response:
var filestream = fs.createReadStream(file);
filestream.pipe(limitStream).pipe(res);
fwiw: every time you call pipe() you get back a new stream. The above is the same as this:
var filestream = fs.createReadStream(file);
var throttleStream = filestream.pipe(limitStream);
throttleStream.pipe(res);
This is important to understand because it's tempting to do this, but it won't do what you expect:
var filestream = fs.createReadStream(file);
filestream.pipe(limitStream);
filestream.pipe(res);

NodeJS file system fs - Is it possible to create a file to be downloaded to downloads folder

var fs = require('fs');
var stream = fs.createWriteStream("my_file.txt");
stream.once('open', function(fd) {
stream.write("My first row\n");
stream.write("My second row\n");
stream.end();
});
If I have the code above , how would I go about downloading my_file.txt to a downloads folder on a users device (i.e laptop or mobile device).
So I have chat messages on screen and I want to write them to file the user can download for reference!
Okay, If you have file you can download it as:
app.get('/download', function (req, res) {
var file = 'file_path_goes_here';
var filename = path.basename(file);
var mimetype = mime.lookup(file);
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type', mimetype);
var filestream = fs.createReadStream(file);
filestream.pipe(res);
});
Complete Code is available as node-cheat at express_server_download_file, run node app followed by npm install express mime.

Send zip created by node-zip

Let's say you create a zip file in-memory following the example from node-zip's documentation:
var zip = new require('node-zip')()
zip.file('test.file', 'hello there')
var data = zip.generate({type:'string'})
How do you then send data to a browser such that it will accept it as a download?
I tried this, but the download hangs at 150/150 bytes AND makes Chrome start eating 100% CPU:
res.setHeader('Content-type: application/zip')
res.setHeader('Content-disposition', 'attachment; filename=Zippy.zip');
res.send(data)
So what's the proper way to send zip data to a browser?
Using the archiver and string-stream packages:
var archiver = require('archiver')
var fs = require('fs')
var StringStream = require('string-stream')
http.createServer(function(request, response) {
var dl = archiver('zip')
dl.pipe(response)
dl.append(new fs.createReadStream('/path/to/some/file.txt'), {name:'YoDog/SubFolder/static.txt'})
dl.append(new StringStream("Ooh dynamic stuff!"), {name:'YoDog/dynamic.txt'})
dl.finalize(function (err) {
if (err) res.send(500)
})
}).listen(3000)
I recommend you to use streams for this approach.
var fs = require('fs');
var zlib = require('zlib');
var http = require('http');
http.createServer(function(request, response) {
response.writeHead(200, { 'Content-Type': 'application/octet-stream' });
var readStream = fs.createReadStream('test.file');
var unzipStream = zlib.createUnzip();
readStream.pipe(unzipStream.pipe(response));
}).listen(3000);
This will properly not work in real world (as I am not common with zlib) but it may give you the direction

Resources