Jos*_*per 6 amazon-s3 amazon-web-services cors amazon-cloudfront
我有一个 S3 存储桶作为源,还有一个 CloudFront 发行版,从中提供流媒体 a/v。
我还有一个 EC2 实例,从测试域提供网页,该测试域使用 videojs 显示视频作为测试。
如果我启动 VLC 媒体播放器并使用 CloudFront URL 观看视频,我会看到并听到媒体。因此,如果我不必处理 CORS,则此配置确实可以满足内容。
但是,当我尝试从 EC2 实例的网页查看内容时,我遇到了 CORS 问题。
使用 Firefox 并观察开发人员工具中的“网络”选项卡,我发现 Firefox 可以毫无问题地获取初始 .mpd URL。但是,后续文件(*.cmfv、*.cmfa,全部嵌入在 .mpd XML 中)在预检检查(OPTIONS 方法调用)中显示“CORS 缺少允许来源”。引发 OPTIONS 请求的 GET 请求会出现 NS_ERROR_DOM_BAD_URI 错误,并且永远不会发送。
使用curl,我模仿了来自Firefox的请求:
curl -H "origin: https://my.happy.url" -H "referer: https://my.happy.url" -H "Access-Control-Request-Headers: range" -H "Access-Control-Request-Method: GET" -X OPTIONS -v https://gobbledygook.cloudfront.net/content/10%20Minutes%20Of%20Coding%20Torture_6.cmfv
我得到这样的回应:
> OPTIONS /content/10%20Minutes%20Of%20Coding%20Torture_6.cmfv HTTP/2
> Host: gobbledygook.cloudfront.net
> user-agent: curl/7.79.1
> accept: */*
> origin: https://my.happy.url
> referer: https://my.happy.url
> access-control-request-headers: range
> access-control-request-method: GET
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< content-length: 0
< date: Tue, 16 Nov 2021 19:25:54 GMT
< server: AmazonS3
< vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
< x-cache: Hit from cloudfront
< via: 1.1 aaaaaaaiiiiiiiggggghhhhh.cloudfront.net (CloudFront)
< x-amz-cf-pop: IUD69-C2
< x-amz-cf-id: pHptphptmQ2lILrG9dpKVZIXT7Dhm_HSDVnBPijf7KcS7ZsLkKA==
< age: 1603
<
* Connection #0 to host gobbledygook.cloudfront.net left intact
Run Code Online (Sandbox Code Playgroud)
...我发现明显缺乏 Access-Control-Allow-Origin,这是我在 JavaScript 控制台日志记录中看到的抱怨。
然而,如果我使用curl 来模仿最初的GET 请求:
curl -H "origin: https://my.happy.url" -H "referer: https://my.happy.url" -H "range: bytes=658-4657" -v https://gobbledygook.cloudfront.net/content/10%20Minutes%20Of%20Coding%20Torture_6.cmfv
...我明白了:
> Host: gobbledygook.cloudfront.net
> user-agent: curl/7.79.1
> accept: */*
> origin: https://my.happy.url
> referer: https://my.happy.url
> range: bytes=658-4657
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 206
< content-type: video/mp4
< content-length: 4000
< date: Wed, 17 Nov 2021 11:54:27 GMT
< last-modified: Wed, 10 Nov 2021 15:36:31 GMT
< etag: "a2155000203fcc7e173acdc053a75cd1"
< x-amz-version-id: mfCll81lDxmeTyDIYmsoKFINElW2AmE1
< accept-ranges: bytes
< server: AmazonS3
< vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
< content-range: bytes 658-4657/8320198
< access-control-allow-origin: *
< x-cache: Miss from cloudfront
< via: 1.1 aaaaaaaiiiiiiiggggghhhhh.cloudfront.net (CloudFront)
< x-amz-cf-pop: IAD66-C2
< x-amz-cf-id: hd-iBmLikeSmoNEYznT3SoWKNDERIGHE-gtjH2U3JlQDlwccL6SdQ==
<
Run Code Online (Sandbox Code Playgroud)
请注意包含access-control-allow-origin: *OPTIONS 缺少的标头。它确实获取了内容。因此,在我看来,唯一阻碍这一点的是 OPTIONS 查询缺少 access-control-allow-origin 标头。除非我遗漏了一些东西(在这一点上这是可能的......我可能在这方面花费了太多时间,并且可能会因为看到解决方案而目光短浅)。
CloudFront 发行版的行为设置为允许 GET、HEAD 和 OPTIONS 方法,并且启用了“缓存 HTTP 方法”OPTIONS 复选框,因此它应该缓存 OPTIONS。
分发行为的缓存策略包括以下标头:
并且所有 cookie 均已启用(这对于这种情况并不重要)。
TTL 设置的最小值为 0,最大值为 31536000,默认值为 86400,但我怀疑这是否重要。
分发行为的源请求策略包括以下标头:
这是 CORS-S3Origin 托管策略。
分配行为的响应标头策略已启用“配置 CORS”,其中包含以下内容:
S3 存储桶的“权限”选项卡中有 CORS 设置:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"ETag",
"Access-Control-Allow-Origin",
"Connection",
"Content-Length"
],
"MaxAgeSeconds": 3000
}
]
Run Code Online (Sandbox Code Playgroud)
该网页使用以下代码(带有一点PHP)来播放内容(在脚本标签中):
const dashjsCallback = (player, mediaPlayer) => {
if (videojs && videojs.log) {
mediaPlayer.getDebug().setLogTimestampVisible(false);
}
};
videojs.Html5DashJS.hook('beforeinitialize', dashjsCallback);
const el = document.getElementsByTagName('video')[0];
const manifest = "/content/<?php echo $policy_stream_name ?>";
const mimeType = "application/dash+xml";
const player = videojs(el, {
"controls":true,
"autoplay":true,
"preload":"auto",
"fluid":"true",
});
player.src({
src: 'https://gobbledygook.cloudfront.net' + manifest,
type: mimeType,
});
player.play();
Run Code Online (Sandbox Code Playgroud)
文档中包含以下 HTML:
<video
id="my-video"
class="video-js vjs-default-skin"
controls
preload="auto"
height="480"
data-setup="{}"
crossorigin="anonymous"
>
<p class="vjs-no-js">This video requires JavaScript.</p>
</video>
Run Code Online (Sandbox Code Playgroud)
我还使用这些设置使发行版的缓存内容失效,并等待了 24 小时才再次尝试查看,但我仍然无法通过 videojs 播放器流式传输视频。我已经用尽了我的谷歌功能,现在向你,温柔的读者寻求帮助。我如何说服 videojs 播放在 VLC 中完美播放的内容?
我通过在 CloudFront 中设置 CORS 以及设置 Bucket CORS 解决了这个问题。我的 Bucket CORS 已设置但不起作用,您还需要为 CloudFront CORS 设置 CORS。在这里您可以找到对我有帮助的解决方案。
| 归档时间: |
|
| 查看次数: |
6134 次 |
| 最近记录: |