1

I would like to force a download of an image stored in Firebase Storage, but the download attribute in HTML anchors does not support cross-domain and I can't change the content-type to application/octet-stream because it's used to generate a thumbnail.

How can it be done ?

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
le0
  • 791
  • 2
  • 8
  • 19

2 Answers2

4

In this case, you cannot use a simple 'download' in html anchors.

What you can do is sending your download request through javascript.

There is an official sample for downloading.

storageRef.child('images/stars.jpg').getDownloadURL().then(function(url) {
  // `url` is the download URL for 'images/stars.jpg'

  // This can be downloaded directly:
  var xhr = new XMLHttpRequest();
  xhr.responseType = 'blob';
  xhr.onload = function(event) {
    var blob = xhr.response;
  };
  xhr.open('GET', url);
  xhr.send();

  // Or inserted into an <img> element:
  var img = document.getElementById('myimg');
  img.src = url;
}).catch(function(error) {
  // Handle any errors
});
tim
  • 1,454
  • 1
  • 25
  • 45
  • 1
    I did it and I am receiving this error: "Access to XMLHttpRequest at *storage_url* from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource." – le0 Nov 26 '18 at 02:52
  • Oh, I see. this should help, About [how to use CORS](https://www.html5rocks.com/en/tutorials/cors/) – tim Nov 26 '18 at 02:57
  • 1
    Thanks. I configured the CORS and the error above disappeared but nothing is happening when call xhr.send(). I am not setting the image.src because the idea is to force download. – le0 Nov 26 '18 at 03:10
  • it will be great, if you post your codes in question, it will be easy for other users to help and identity the issues. – tim Nov 26 '18 at 03:34
  • I think your codes are correct, the reason you cannot get the images is because there is no `img` to show or `form` to download. this should help by [creating a download form](https://stackoverflow.com/questions/11620698/how-to-trigger-a-file-download-when-clicking-an-html-button-or-javascript) or set it to an `img`, `var img = document.getElementById('myimg'); img.src = url;` – tim Nov 27 '18 at 00:26
  • Great. It solved ! I've updated the codepen above with the solution. – le0 Nov 27 '18 at 02:03
0

I had a similiar issue with downloading an mp4 video file. The browser seemed to ignore any download attribute in my html anchors. So my solution was to request the Blob from firebase like so wich also helps hiding an url to the file in storage:

await getBlob(storageRef(storage, path))
  .then((blob) => {
    downloadUrl.value = URL.createObjectURL(blob);
  }

now the browser (including ios) directly triggers a download instead of opening the video in the browser by clicking the anchor:

<a :href="downloadUrl" download="videofile">Download</a>
Philip
  • 201
  • 2
  • 10