1

So I have this code:

downloadFile: async (req, res) => {
    var mongoose = require('mongoose');
    var Grid = require('gridfs-stream');
    mongoose.connect(config.db, {useNewUrlParser: true},).catch(e => console.log(e));
    var conn = mongoose.connection;
    Grid.mongo = mongoose.mongo;
    var gfs = Grid(conn.db);
    var file_id = req.params.logoId;
    console.log(file_id);
    return gfs.files.find({_id: file_id}).toArray(function (err, files) {
        if (err) {
            console.log(err);
        }
        if (files.length > 0) {
            console.log(files[0]);
            var mime = files[0].contentType;
            var filename = files[0].filename;
            res.set('Content-Type', mime);
            res.set('Content-Disposition', "inline; filename=" + filename);
            var read_stream = gfs.createReadStream({_id: file_id});
            read_stream.pipe(res);
            return res;
        } else {
            console.log('File not found')
        }
    });
}

Executing it causes my browser to download the physical file via the browser. How can I redirect it to be saved on the server(?) and use it as a logo on the website?

mihai
  • 37,072
  • 9
  • 60
  • 86
Alex Ironside
  • 4,658
  • 11
  • 59
  • 119

1 Answers1

0

You are currently reading the file from gfs and piping to the response. Instead, you could simply pipe to file:

var read_stream = gfs.createReadStream({_id: file_id});
var imgFile = fs.createWriteStream("images/logos/logo.jpg");
var write_stream = read_stream.pipe(imgFile);

This operation should be performed on server startup. I don't think it's a good idea to perform inside a request, if the file is simply a logo. However if you still wish to do it inside a request, you would need to handle the stream finish event, and only return a response when the write_stream has finished processing the file:

write_stream.on("finish", function() { 
  ...
  res.send(...);
});
mihai
  • 37,072
  • 9
  • 60
  • 86
  • The thing is. Users can upload their logos. I can have 6k logos. I cannot download this at the startup of the server. Do you know of a better way of doing it? – Alex Ironside Nov 01 '18 at 10:41
  • I see. In this case you have asked the wrong question. It is better to serve it directly by piping to the response, like you do it in your code, instead of downloading it to the file system. You are probably setting the incorrect headers, so the file is presented as a download instead of just being displayed in the browser. See this https://stackoverflow.com/questions/5823722/how-to-serve-an-image-using-nodejs/40899767#40899767 perhaps it will help you serve the file correctly. – mihai Nov 01 '18 at 10:50
  • What am I supposed to do with the `write_stream` variable? Return it? I read through the question, but it's really confusing – Alex Ironside Nov 02 '18 at 15:13