Сохранение файла, загруженного с помощью gridfs, для использования на веб-сайте

Итак, у меня есть этот код:

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')
        }
    });
}

Его выполнение заставляет мой браузер загружать физический файл через браузер. Как я могу перенаправить его для сохранения на сервере (?) И использовать в качестве логотипа на веб-сайте?

"а пользователь в качестве логотипа на сайте?" поправьте пожалуйста, непонятно, о чем вы здесь спрашиваете.

mihai 01.11.2018 11:09

Файл представляет собой логотип. Мне нужно использовать этот файл в базе данных и отобразить его на веб-сайте. Раньше пользовался этим <img="images/logos/logo.jpg">. Как я могу сделать что-то подобное после загрузки картинки?

Alex Ironside 01.11.2018 11:12

попросите сервер загрузить его на images/logos, ваш URL-адрес img все равно будет работать

mihai 01.11.2018 11:17

да. У меня вопрос, как сохранить его на сервере по этому пути?

Alex Ironside 01.11.2018 11:18
1
4
257
1

Ответы 1

В настоящее время вы читаете файл из gfs и отправляете ответ по конвейеру. Вместо этого вы можете просто передать файл по конвейеру:

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

Эта операция должна выполняться при запуске сервера. Я не думаю, что это хорошая идея выполнять внутри запроса, если файл представляет собой просто логотип. Однако, если вы все же хотите сделать это внутри запроса, вам нужно будет обработать событие потока finish и вернуть ответ только тогда, когда write_stream завершит обработку файла:

write_stream.on("finish", function() { 
  ...
  res.send(...);
});

Дело в том. Пользователи могут загружать свои логотипы. У меня может быть 6к логотипов. Я не могу загрузить это при запуске сервера. Вы знаете, как это сделать лучше?

Alex Ironside 01.11.2018 11:41

Понятно. В этом случае вы задали неправильный вопрос. Лучше обслуживать его напрямую, передавая ответ по конвейеру, как вы делаете это в своем коде, вместо того, чтобы загружать его в файловую систему. Вероятно, вы устанавливаете неправильные заголовки, поэтому файл отображается как загружаемый, а не просто отображается в браузере. См. Этот stackoverflow.com/questions/5823722/…, возможно, он поможет вам правильно обслуживать файл.

mihai 01.11.2018 11:50

Что мне делать с переменной write_stream? Верни это? Я прочитал вопрос, но это действительно сбивает с толку

Alex Ironside 02.11.2018 16:13

Другие вопросы по теме