Я хочу иметь возможность отправлять файл, загруженный из облака Google, непосредственно клиенту, и мне не нужно сначала сохранять на моем сервере, а затем создавать загрузку клиенту из сохраненной версии на моем сервере, потому что это замедляет процесс, так как файл загружается два раза, сначала из облака Google на мой собственный сервер, а затем с моего собственного сервера на клиент.

router.get("/:filename", async(req, res) => {
  try {
    // Grab filename from request parameter
    const fetchURL =req.params.filename;
    const file = await File.findOne({fetchURL});
    const srcFileName = file.originalname;
  // Call GCS with bucketName and check the file method with srcFileName and check again with download method which takes download path as argument
    storage
      .bucket(bucketName)
      .file(srcFileName)
      .download({
        destination: path.join(process.cwd(), "downloads", srcFileName)
      })
      .then(() =>
        res.download(path.join(process.cwd(), "downloads", srcFileName), err =>
          err ? console.log(err) : null
        )
      )
      .catch(err =>res.status(400).json({
        message: err.message
      }));
  } catch (err) {
    res.status(res.statusCode).json({
      message: `There was an error downloading your file. ${err.message}`
    });
  }
});

7
BoyePanthera 8 Апр 2020 в 13:31
1
Если вы не хотите загружать файл на свой сервер перед тем, как предоставить его общественности, альтернативой может быть использование Подписанные URL-адреса, которые могут предоставить ограниченный по времени доступ к ресурсу любому, независимо от того, есть ли у него аккаунт Google. Здесь< /a> вы также узнаете, как легко генерировать эти подписанные URL-адреса и передавать их пользователю, в вашем случае клиенту, без загрузки файла на ваш сервер. Я надеюсь, что это помогает.
 – 
Christopher Rodriguez Conde
10 Апр 2020 в 12:45
Спасибо, @ChristopherRodriguezConde, вы совершенно правы, я обнаружил это в документации, так как не мог получить никаких ответов в нерабочее время, поэтому я создал подписанный URL-адрес, действительный в течение 10 минут, и отправил клиенту.
 – 
BoyePanthera
10 Апр 2020 в 17:57
Политика моей организации запрещает общедоступные URL-адреса. Должен ли быть способ получить содержимое файла напрямую в программе?
 – 
Nikhil VJ
4 Авг 2021 в 13:25

1 ответ

Это работает для меня на сервере NodeJS+Express:

const {Storage} = require('@google-cloud/storage');
const storage = new Storage({projectId, keyFilename}); 

router.get('/:id', async function (req, res) {

   let fileName = 'test.jpg'; //For example
   let contetType = 'image/jpg;' //For example
   res.writeHead(200, {
    'Content-Disposition': `attachment;filename=${filename}`,
    'Content-Type': `${contetType}`
   });

   await storage
   .bucket('my-bucket')
   .file(`Images/${req.params.id}/${filename}`)
   .createReadStream() //stream is created
   .pipe(res);
   });}
4
Shoom Kloom 23 Авг 2022 в 22:52
Не могли бы вы выложить полную версию своего кода, как я его сейчас вижу, это только его часть? Или вот что это?
 – 
Lazarus
12 Авг 2022 в 14:43
Это весь код get api. Все остальное — это просто узел + экспресс.
 – 
Shoom Kloom
23 Авг 2022 в 22:50