I set all my GCP bucket items to be accessible to the public. I also set cors on my bucket using gsutil cors set cors-config.json gs://myBucketName
. My cors config file looks like this: [{"origin": ["http://example.com"],"responseHeader": ["Content-Type"],"method": ["GET"],"maxAgeSeconds": 3600}]
. Now I have two problems. The first one is when I try to access an audio file from my bucket and play it on my website I get the error Access to audio at 'http://publicIpAddr/fileName.mp4' from origin 'http://example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
NOTE: I am accessing the file via an IP address because I set up a load balancer with cloud cdn enabled which cached objects matching a path pattern I specified.
This is how I am accessing the audio file on my website:
JS
const audioElem = document.querySelector('#audioElem')
audioElem.crossOrigin = 'use-credentials';
audioElem.setAttribute('src', 'http://publicIpAddr/fileName.mp4')
audioElem.play()
The second problem is if I remove the audioElem.crossOrigin = 'use-credentials';
line from my JS code. The audio starts playing without an error. The issue is the audio plays from any domain regardless of it being specified as an allowed origin on my bucket cors options. Why is this happening? What am I missing? Thanks in advance.
If you've configured CORS correctly, just wait – even up to about two days.
If it still doesn't work, re-check your config. Read below for details.
I'm not exactly sure. (I'm actually having a similar issue and will report my findings.)
If you have configured CORS correctly, the key is you have to wait several days before it actually takes effect.
Exactly how much time, frankly I'm not sure, but it seems to be about two days. If it doesn't work by then, re-check your configuration. See the below list to make sure you've configured it correctly. Google is very strict, and having, e.g., invalid origin values for your CORS header will cause the header to just be left out (but Google won't tell you if they're valid).
I'd recommend to start by checking to see if the Access-Control-Allow-Origin
header is present when loading the audio directly from the storage bucket. If it is present there, but not on the request via your reverse proxy, then the problem is that the reverse proxy is not passing the header on.
A few other minor things to check for:
gcloud storage buckets update gs://bucket-name --cors-file="local/path/cors.json"
gsutil cors set local/path/cors.json gs://bucket-name
gcloud storage buckets describe gs://bucket-name --format="json(cors_config)"
gsutil cors get gs://bucket-name
gcloud
/ gsutil
command runs in the correct project.
gcloud init
if not run already, otherwisegcloud config set project project-name
gcloud config get project
http://example.com:8080
https://example.net
https://something.com/
(trailing /)htps://example.com
(bad protocol)http://example.com:65536
(port out-of-range)http://example.com:
(colon, no port)http://Example.com
(case-sensitive)https://example.com:443
(does not match https://example.com
)Not everything requires CORS. It mainly only applies to the XMLHttpRequest
and fetch
APIs.
<script>
tags, for instance, can be loaded from any domain without needing an Access-Control-Allow-Origin
header. This is what made JSONP possible even before CORS existed.
The same also applies to <audio>
tags, <img>
tags, and a number of other tags. The resources they load bypass any CORS policies.
With that said, if you read over the details of the crossorigin
attribute for the <audio>
tag, it mentions the concept of tainted resources. A tainted resource, if used in some other way, taints what it's used on.
For instance, if an image is loaded without respecting CORS, it is tainted. If it's then drawn on a <canvas>
the canvas also becomes tainted. Tainted canvases then have additional restrictions. e.g., context.getImageData
/ canvas.toDataURL
will no longer be allowed.