我有一个S3存储桶作为源,以及一个CloudFront分发服务从中流式传输音视频。
我还有一个EC2实例,从测试域名提供Web页面,并使用videojs作为测试来显示视频。
如果我启动VLC媒体播放器并使用CloudFront URL查看视频,则可以同时看到和听到媒体。 因此,如果我不必处理CORS,这个配置可以提供内容。
但是,当我尝试从我的EC2实例的网页中查看内容时,遇到了CORS问题。
使用Firefox并观察开发工具中的网络选项卡,我发现Firefox无问题地获取了初始的.mp4 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请求中缺少了“access-control-allow-origin: *”标头。它实际上已经获取了内容。因此,我认为唯一阻止这个问题的是缺少OPTIONS查询的access-control-allow-origin标头。除非我遗漏了什么(在这一点上可能是可能的...我已经花了太多时间在这个问题上,并且可能会从看到解决方案的角度狭窄)。
CloudFront分发的行为设置允许GET、HEAD和OPTIONS方法,并启用了“缓存HTTP方法”的OPTIONS复选框,因此应该缓存OPTIONS。
分发行为的缓存策略包括以下标头:
- Origin - Access-Control-Request-Method - Access-Control-Allow-Origin - Access-Control-Request-Headers
所有cookie都已启用(尽管这对本情况无关紧要)。
TTL设置的最小值为0,最大值为31536000,默认值为86400,但我怀疑这并不重要。
分发行为的Origin请求策略包括以下标头:
- Origin - Access-Control-Request-Headers - Access-Control-Request-Method
这是CORS-S3Origin受控策略。
分发行为的响应标头策略启用了“配置CORS”,具有以下内容:
- Access-Control-Allow-Origin:所有来源 - Access-Control-Allow-Headers:所有标头 - Access-Control-Allow-Methods:所有HTTP方法 - Access-Control-Expose-Headers:所有标头 - Access-Control-Max-Age:600 - 检查覆盖来源
S3存储桶在其权限选项卡中具有CORS设置。
该网页使用以下代码(包括少量 PHP 代码)来播放内容(在 script 标签中):
在文档中有以下HTML代码:
如果我启动VLC媒体播放器并使用CloudFront URL查看视频,则可以同时看到和听到媒体。 因此,如果我不必处理CORS,这个配置可以提供内容。
但是,当我尝试从我的EC2实例的网页中查看内容时,遇到了CORS问题。
使用Firefox并观察开发工具中的网络选项卡,我发现Firefox无问题地获取了初始的.mp4 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
...我发现缺少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==
<
请注意,在OPTIONS请求中缺少了“access-control-allow-origin: *”标头。它实际上已经获取了内容。因此,我认为唯一阻止这个问题的是缺少OPTIONS查询的access-control-allow-origin标头。除非我遗漏了什么(在这一点上可能是可能的...我已经花了太多时间在这个问题上,并且可能会从看到解决方案的角度狭窄)。
CloudFront分发的行为设置允许GET、HEAD和OPTIONS方法,并启用了“缓存HTTP方法”的OPTIONS复选框,因此应该缓存OPTIONS。
分发行为的缓存策略包括以下标头:
- Origin - Access-Control-Request-Method - Access-Control-Allow-Origin - Access-Control-Request-Headers
所有cookie都已启用(尽管这对本情况无关紧要)。
TTL设置的最小值为0,最大值为31536000,默认值为86400,但我怀疑这并不重要。
分发行为的Origin请求策略包括以下标头:
- Origin - Access-Control-Request-Headers - Access-Control-Request-Method
这是CORS-S3Origin受控策略。
分发行为的响应标头策略启用了“配置CORS”,具有以下内容:
- Access-Control-Allow-Origin:所有来源 - Access-Control-Allow-Headers:所有标头 - Access-Control-Allow-Methods:所有HTTP方法 - Access-Control-Expose-Headers:所有标头 - Access-Control-Max-Age:600 - 检查覆盖来源
S3存储桶在其权限选项卡中具有CORS设置。
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"ETag",
"Access-Control-Allow-Origin",
"Connection",
"Content-Length"
],
"MaxAgeSeconds": 3000
}
]
该网页使用以下代码(包括少量 PHP 代码)来播放内容(在 script 标签中):
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();
在文档中有以下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>
我还使用这些设置使分发的缓存内容无效,并等待了24小时后再次尝试查看,但我仍然无法通过videojs播放器流式传输视频。我已经用尽了我的谷歌技巧,现在转向你,亲爱的读者,请求帮助。我该如何说服videojs播放这个在VLC中完美播放的内容?
--disable-web-security
参数浏览到页面并查看内容,但这不是我想要的工作方式。 - Joseph Van Riper