We are generating resumable upload url through the cloud storage JSON API from our App Engine application which are used on mobile as well as a web app. In the web app, using XmlHttpRequest to upload a file with the resumable upload url we get the following error :
XMLHttpRequest cannot load https://www.googleapis.com/upload/storage/v1beta2/b/... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://ourapp.appspot.com' is therefore not allowed access.
In Chrome developer tools, the network log show a first OPTIONS request with the appropriate "Origin" request header and "Access-Control-Allow-Origin" response header but the following PUT request fails as mentioned.
The cors xml on our bucket looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<CorsConfig>
<Cors>
<Origins>
<Origin>*</Origin>
</Origins>
<Methods>
<Method>PUT</Method>
<Method>GET</Method>
<Method>POST</Method>
<Method>HEAD</Method>
<Method>DELETE</Method>
<Method>OPTIONS</Method>
</Methods>
<ResponseHeaders>
<ResponseHeader>*</ResponseHeader>
</ResponseHeaders>
<MaxAgeSec>1800</MaxAgeSec>
</Cors>
</CorsConfig>
Any suggestions are welcome.
Thanks.
The problem is not with the CORs document shown above. One can upload files with xhr if the xhr request is formdata as described here: http://www.html5rocks.com/en/tutorials/file/xhr2/#toc-sending . If the request is not FormData we get the 'Access-Control-Allow_Origin' error.
This works for me:
See a full working node.js example here: https://github.com/sfarthin/crop-rotate-and-sample-in-browser
Ran into this problem and discovered that it was due to a missing "origin" header in the initial POST request coming from App Engine.
My POST request contains content-length (set to 0), x-upload-content-type, and origin and all is well.
[1]https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload#resumable
I had the same problem, and the solution was to add a Header
Origin: "https://ourapp.appspot.com"
to the initial resumable request.However, some librares, for example
sun.net.www.protocol.http.HttpURLConnection
doesn't allow you to change theOrigin
header because of the following variable :restrictedHeaders = new String[]{"Access-Control-Request-Headers", "Access-Control-Request-Method", "Connection", "Content-Length", "Content-Transfer-Encoding", "Host", "Keep-Alive", "Origin", "Trailer", "Transfer-Encoding", "Upgrade", "Via"};
My workaround was to create a new HttpRequest with a library that allows to update the
Origin
header. I used Okhttp in my case (as former Android developper).This is a known problem with using resumable upload with the JSON API. I assume the "origin" used to start the resumable upload and the "origin" used to upload data are different in your case, right?
There are two parts involved in this issue:
1) When using resumable upload protocol, the "origin" from the first (start upload) request is always used to decide the "access-control-allow-origin" header in the response, even if you use a different "origin" for subsequent requests.
2) The CORS config in GCS only works for the XML API. I think our documentation could use some improvement to make this more clear, right now it's only kind of mentioned here (https://developers.google.com/storage/docs/cross-origin#Sending-a-Cross-Domain_Request) if you click through the link to see what request URIs will be responsive to the CORS config. The JSON API ignores the CORS config, and will always allow cross-origin access for the "origin" in the request.
So if you use resumable upload with JSON API, it will only use the "origin" from the first request, and set "access-control-allow-origin" header to that origin. Thus, if the origin changes in subsequent upload requests, they will not work.
Currently you have two ways to work around this issue:
1) Use the same origin for the first and subsequent requests.
2) Switch to use the XML API, and set the CORS config to <Origin>*</Origin>.
The endpoint
https://www.googleapis.com
is not allowing Cross-Origin Resource Sharing (CORS). That means all browsers will prevent requests when issued from a website which is not running on the origin host (www.googleapis.com).Make sure you configured CORS for your bucket e.g.:
If it is still not working set
<Origin>*</Origin>
, try with curl and report the outcome.