Download From Amazon Simple Storage Service(S3) Buckets using JavaScript

August 05, 2019  2 minute read  

Learn how to download from Amazon S3 buckets in your web application(frontend) using JavaScript.

Configure CORS Policy

First of all, configure Cross-Origin Resource Sharing(CORS) policy for your S3 bucket before proceeding as you may get CORS error when you download using fetch and other JavaScript APIs.

Check out Handle Amazon S3 Download No Access-Control-Allow-Origin Header Error article to learn how to set up CORS policy for an S3 bucket.

Download From Amazon S3

This is not a comprehensive list of all possible ways to download from Amazon S3. They are just methods that I would like to share with you.

Your Amazon S3 item url looks like this. If it is a presigned url, it has several signature and expiry parameters appended to the url. The following url will be referred as YOUR-S3-ITEM-URL throughout the rest of this article.


https://bucket-name.s3.amazonaws.com/path-to-item.extension

HTML Anchor element <a>

This is probably the easiest way to download from an S3 url. You can set as S3 url as the value for your anchor element’s href attribute. In addition, you can style your anchor element to look like a button.


<a href='YOUR-S3-ITEM-URL' 
   download='ITEM-NAME.extension'>Download!</a>

Fetch and Achor Element

To enable automatic download, you can simulate a click on an anchor element using anchor element’s click() method. You can specify the downloaded item name plus file extension using anchor element’s download attribute, for example, ‘my-item.text’.

fetch('YOUR-S3-ITEM-URL', {method: 'GET'})
  .then(res => {
    return res.blob();
  })
  .then(blob => {
    var url = window.URL.createObjectURL(blob);
    var a = document.createElement('a');
    a.href = url;
    a.download = 'myItem.extension';
    document.body.appendChild(a); 
    a.click();  
    setTimeout(
      _ => { window.URL.revokeObjectURL(url); }, 
      60000); 
    a.remove(); 
  })
  .catch(err => {
    console.error('err: ', err);
  })

Fetch and FileSaver

To reduce risk of browser incompatibility but at the expense of dependency, you can use FileSaver.js which is a maintained open source script on your website.

For self improvement, it is a good idea to read what is inside FileSaver.js to see how saveAs polyfill is implemented.

Include FileSaver.js File

Using FileSaver on your website, you can use saveAs polyfill method which automatically downloads and saves a file(blob) item to your user’s local machine.

You can download FileSaver.js and include it in your web application. It is better to minimize it if you use it for production.

Then, to use it, you can include the following script within ‘<head>’ element of your index.html with the correct path to where you put FileSaver.js.


<script 
  type='text/javascript'
  src='assets/js/FileSaver.js'></script>

NPM

On the other hand, you can also install FileSaver using npm.


npm install file-saver --save

# if TypeScrirpt
npm install @types/file-saver --save-dev

saveAs example

After including FileSaver.js script or installing FileSaver package, you can use it to enable automatic download of S3 items to your user’s device.

fetch('YOUR-S3-ITEM-URL', {method: 'GET'})
  .then(res => {
    return res.blob();
  })
  .then(blob => {
    saveAs(blob, 'myItem.extension');
  })
  .catch(err => {
    console.error('err: ', err);
  })

Summary

Choose the way to download from S3 that is user-friendly for your users and use case so that you can provide the best user experience.

Check out Download From Amazon (S3) Private Buckets Using Presigned URLs article if you are interested in keeping your bucket private and at the same time letting users download from your S3 buckets.

Support Jun

Thank you for reading!    Support JunSupport Jun

Support Jun on Amazon US

Support Jun on Amazon Canada

If you are preparing for Software Engineer interviews, I suggest Elements of Programming Interviews in Java for algorithm practice. Good luck!

You can also support me by following me on Medium or Twitter.

Feel free to contact me if you have any questions.

Comments