我将所有 GCP 存储桶项目设置为可供公众访问。我还使用
gsutil cors set cors-config.json gs://myBucketName
在我的水桶上设置了 cors。我的 cors 配置文件如下所示:[{"origin": ["http://example.com"],"responseHeader": ["Content-Type"],"method": ["GET"],"maxAgeSeconds": 3600}]
。现在我有两个问题。第一个是当我尝试从我的存储桶访问音频文件并在我的网站上播放它时,我收到错误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.
注意: 我通过 IP 地址访问文件,因为我设置了启用了云 CDN 的负载均衡器,该负载均衡器缓存与我指定的路径模式匹配的对象。
这就是我在我的网站上访问音频文件的方式:
JS
const audioElem = document.querySelector('#audioElem')
audioElem.crossOrigin = 'use-credentials';
audioElem.setAttribute('src', 'http://publicIpAddr/fileName.mp4')
audioElem.play()
第二个问题是如果我从 JS 代码中删除
audioElem.crossOrigin = 'use-credentials';
行。音频开始播放,没有错误。问题是音频从任何域播放,无论它是否被指定为我的存储桶 cors 选项上允许的来源。为什么会发生这种情况?我缺少什么?预先感谢。
我不太确定。 (我实际上也遇到了类似的问题,并将报告我的发现。)
我建议首先检查直接从存储桶加载音频时是否存在
Access-Control-Allow-Origin
标头。如果它存在,但不在通过反向代理的请求上,那么问题是反向代理没有传递标头。
并非所有事情都需要 CORS。主要仅适用于
XMLHttpRequest
和 fetch
API。
例如,可以从任何域加载 <script>
标签,而不需要 Access-Control-Allow-Origin
标头。这就是在 CORS 存在之前就使 JSONP 成为可能 的原因。
这同样适用于
<audio>
标签、<img>
标签和许多其他标签。它们加载的资源绕过任何 CORS 策略。
话虽如此,如果您阅读了 crossorigin
标签的
<audio>
属性的详细信息,它提到了 tainted 资源的概念。 受污染的资源,如果以其他方式使用,就会污染它的使用对象。
例如,如果在不考虑 CORS 的情况下加载图像,则会受到污染。如果然后在
<canvas>
上绘制,画布也会被污染。 受污染的画布还有额外的限制。例如,将不再允许使用 context.getImageData
/ canvas.toDataURL
。