1

Using server side logic, I have an ExpressJS API endpoint for getting a file from an S3 bucket. Basically, it sends back the file like this:

const downloadFileFromS3Bucket = async (req, res, next) => {
  try {
   // ...
   await s3.getObject(options, (err, data) => {
      // ...
      if (data) {
        res.send(Buffer.from(data.Body));
      }
    });
  } catch (error) {
    // ...
  }
};

It works as expected (I use postman to check on it).

Now, I want to download that file using a ReactJS app. If, for instance, I use axios to do a request to that endpoint, I get the binary code as shown here as the response: enter image description here

How could I achieve to download the file that is sent to me as you can see on the data property?

Since my api method is a GET method, I also tried using a simple:

window.open('url');

But I have server verification by Bearer token implemented and it won't work.

Multitut
  • 2,089
  • 7
  • 39
  • 63
  • so in react js app you have some button(assuming) when you click on it it should trigger the node js express api and download the file from s3 and pass it to ui so when the user clicks on it in chrome the file gets downloaded is that what you are looking for – Learner Jan 03 '20 at 18:57
  • Thanks @DILEEPTHOMAS, that's what I am trying to achieve but instead I get the response that you can see on the screenshot attached on my question. – Multitut Jan 03 '20 at 20:13
  • Maybe something like this would help you https://stackoverflow.com/questions/41938718/how-to-download-files-using-axios – Zoilo Reyes Jan 03 '20 at 20:56

1 Answers1

1

Two ways to achieve the goal

  1. the javascript way
// first fetch blob from server
const res = await fetch('http://api_endpoint')
const blob = res.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'filename.txt';
document.body.appendChild(a);
a.click();
  1. make the response downloadable by using stream and attachment header
const downloadFileFromS3Bucket = async (req, res, next) => {
   const filename = `filename`;
   const fileType = `application/json`;

   res.setHeader('Content-disposition', `attachment; filename=${filename}`);
   res.setHeader('Content-type', fileType);
   s3.getObject(options).createReadStream().pipe(res);
};
MarkoCen
  • 2,189
  • 13
  • 24