QubitProducts / gcs-browser-upload

Resumable chunked uploads to Google Cloud Storage from the browser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting a CORS error

hendrikswan opened this issue · comments

Hi there! I'm sorry to bother you with a support issue like this. I'm probably just doing something silly, but when I use gcs-browser-upload I get a cors preflight error.

Using gcs-browser-upload

So when I try and do the following (signedUrl is a url I got from our API):

  const upload = new Upload({
    id: signedUrl,
    url: signedUrl,
    file,
    onChunkUpload: (info) => {
      logger.debug('Chunk uploaded', info);
    },
  });

  await upload.start();

I get this error: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:1234' is therefore not allowed access.

Using axios:

When I use axios using the same signedUrl like this:

  await axios({
    method: 'put',
    url: signedUrl,
    data: file,
    headers: {
      'Content-Type': file.type,
    },
  });

I don't get a CORS error.

Question:

I read on this post http://opreview.blogspot.com/2017/03/how-to-upload-to-google-cloud-storage.html, that you need to make an additional request to gcs to get a resumable url, using your signed url. Do I need to do this, even when I am using your library?

@hendrikswan can you tell me how to use this lib to upload files to gcs? Read funtional test but i haven't understood yet

I followed this working example that just uses XMLHttpRequest (which axios uses internally) - https://github.com/HenrikJoreteg/google-cloud-signedurl-test-case

Before running that test, I had to create a keyfile.json for my service account to authenticate with Google Cloud Storage. (Command reference)

Then I created a bucket-cors-config.json file with these contents:

[{
  "maxAgeSeconds": 86400,
  "method": ["*"],
  "origin": ["*"],
  "responseHeader": ["*"]
}]

and then I ran the following command in a terminal:

gsutil cors set bucket-cors-config.json gs://my-bucket-name

After that, I ran node . to start the project and the upload worked. If you want to make it work with IE11, you must add a line to if (isIE11) { xhr.setRequestHeader('Content-Type', contentType) } after the call to xhr.open().

I will be testing with Axios next. Then I will try out this project (QubitProducts/gcs-browser-upload).

That github project that I linked to shows you the server side of things too, where you generate the signed URL. Now that I have a simple working example without using any external libraries at all, it will be easier to debug whats going on when using axios or this gcs-browser-upload project.

One last note - many things can mess up CORS, such as not sending the right headers. In the case where IE11 was not sending the Content-Type header (something that Chrome does automatically with XMLHttpRequest), I was getting a CORS error.

@hendrikswan @waynebloss sorry for the delayed response - notifications were somehow turned off for this repo, so I had no idea you guys were posting!

When you create a resumable upload URL using the Google Cloud API, you have to provide an origin URL. This is the URL of the website that you will be doing the upload from (in your case, http://localhost:1234). You can see this here in the NodeJS docs for google cloud storage - https://cloud.google.com/nodejs/docs/reference/storage/2.0.x/File#createResumableUpload