Download file from google cloud storage directly to client in nodejs

Viewed 3781

I want to be able to send the file downloaded from google cloud directly to the client and not have to first save on my server then create a download to client from the saved version on my server, cause this make the process slow, as the file is downloaded two times, first from google cloud to my own server then from my own server to client.

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

1 Answers

This works for me in NodeJS+Express server:

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