4
votes

I'm building an app in witch the user see a set of downsized images and than press " ok" for the app to download all of the original files, put them into a zip file and send the zip file.

the app is using polymer, polymerfire, firebase (including the storage).

during the upload of the images i save in the database both the download url and the storage reference for both the original file and the downsized one.

when i put the download url in the iron-image element to show the images in the browser everything works perfectly, the downsized images are shown on the screen. When i try to download the fullsize images via XMLHttpRequest() i get the Cors error. I can't understand why, both request are coming from the same app, why two different cors response?

here is the code for the XMLHttpRequest() (mostly copied from the firebase documentation):

for (var z = 0; z < visita.immagini.length; z++) {
  var immagine =visita.immagini[z]

  var storage = firebase.storage();
  var pathReference = storage.ref('immagini/'+ immagine.original.ref);
  pathReference.getDownloadURL().then(function(url) {

    var xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';
    xhr.onload = function(event) {
      var blob = xhr.response;
      console.log(blob);
    };
    xhr.open('GET', url);
    xhr.send();
  }).catch(function(error) {
      console.log(error);
  });

}

and here is the error response:

XMLHttpRequest cannot load ***** [image link]******. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

note that if i copy the ***** [image link]****** and put in another tab of the browser i can see without problems.

2

2 Answers

4
votes

The section on headers in the Firebase “Deployment Configuration” documentation indicates that to enable cross-origin requests for images, you must add to your firebase.json something like this:

"headers": [ {
  "source" : "**/*.@(jpg|jpeg|gif|png)",
  "headers" : [ {
    "key" : "Access-Control-Allow-Origin",
    "value" : "*"
  } ]
} ]

when i put the download url in the iron-image element to show the images in the browser everything works perfectly, … When i try to download the fullsize images via XMLHttpRequest() i get the Cors error. I can't understand why, both request are coming from the same app, why two different cors response?

Because browsers block cross-origin XHR requests unless the server receiving the requests uses CORS to allow them, by responding with an Access-Control-Allow-Origin: * header.

note that if i copy the ***** [image link]****** and put in another tab of the browser i can see without problems.

That’s expected. When you put a URL into your browser’s address bar, it’s not a cross-origin request—instead it’s just you navigating directly to a URL.

But when you put that URL into the JavaScript for a Web application running at some origin on the Web, then when that request is sent, it’s not you navigating directly to the URL but instead it’s some Web application making a cross-origin request to another Web site.

So browsers by default block such cross-origin requests from JavaScript running in Web apps. But to opt-in to receiving such requests, a site can include the Access-Control-Allow-Origin: * header in its response to the browser. If the browser sees that header, it won’t block the request.

For more details, see the HTTP access control (CORS) article at MDN.

9
votes

I finally found some information on CORS + storage as asked. Check out the firebase docs on storage here: https://firebase.google.com/docs/storage/web/download-files#cors_configuration.

Firstly, you will need gsutil (https://cloud.google.com/storage/docs/gsutil_install).

Then make a file named cors.json somewhere in your project with the following content:

[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]

Finally run: gsutil cors set cors.json gs://<your-cloud-storage-bucket>

These steps worked for me!

This is also answered here: Firebase Storage and Access-Control-Allow-Origin, which I found after answering.