Video.js - HLS => 没有“Access-Control-Allow-Origin”标头 [S3、CloudFront]

maj*_*123 4 amazon-s3 http-live-streaming cors amazon-cloudfront video.js

我在应用程序中使用 video.js 插件播放 HLS 视频时遇到问题。我有一个 HLS 视频(.m3u8、.ts)的 S3 存储,并将其连接到 cloudfront。视频在 safari 上可以正常工作,但在 Chrome 上无法正常工作。当我硬重新加载页面(删除缓存、cookies...)时,它们就可以在 chrome 上工作。

在此输入图像描述

在此输入图像描述

我的配置:

视频.JS:

videojs.Hls.xhr.beforeRequest = function (options) {
      options.headers = {
        "Access-Control-Allow-Origin": "*",
      };
      return options;
    };
Run Code Online (Sandbox Code Playgroud)

S3 存储桶 CORS:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "PUT",
            "POST",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag",
            "Access-Control-Allow-Origin",
            "Connection",
            "Content-Length"
        ],
        "MaxAgeSeconds": 3000
    }
]
Run Code Online (Sandbox Code Playgroud)

云前:

云锋

云锋

Ale*_*pun 5

我遇到了类似的问题。就我而言,某些文件已成功接收,但其他文件(在同一目录中,通过同一机制同时上传)抛出 CORS 错误。经过几天的调查,我修复了它(我希望)。我把我的想法留给未来的研究人员。

  • CORS 支持是在 S3 中实现的,互联网上有很多关于如何配置它的信息。

  • 当请求 CloudFront 链接时,AWS 检查 CloudFront 缓存中是否存在请求的对象。如果是,CloudFront 将返回它。如果没有,CloudFront 从源(在我的例子中是 S3)请求它,缓存它,然后返回。

  • 当请求 S3 链接并且origin请求中存在标头时,S3 返回带access-control-allow-origin标头的文件,否则access-control-allow-origin不将其添加到响应标头中。

  • 当 CloudFront 从源 (S3) 请求文件时,它可以将请求标头(与文件请求一起发送)传输到源 (S3)。这就是为什么您必须将origin标头(以及任何其他标头)添加到“选择要包含在缓存键中的标头”。在这种情况下,如果对 CloudFront 的请求包含origin标头,它也将被发送到 S3。否则,CloudFront 将从 S3 请求不带origin标头的文件,S3 将返回不带标头的文件access-control-allow-origin,不带标头的文件将被缓存并返回到浏览器(CORS 错误)。 标头

  • 现在,缓存和源设置下有 2 个选项:“缓存策略和源请求策略(推荐)”和“旧版缓存设置”(似乎之前没有选项,仅存在“旧版缓存设置”中的设置)。在“缓存策略和源请求策略(推荐)”下有“缓存策略”和“源请求策略 - 可选”部分。如果设置了预定义的推荐策略,则origin标头(和其他)是为“源请求策略 - 可选”预定义的,但不是为“缓存策略”预定义的。老实说,我不明白每个部分的确切含义,但似乎遗留的“选择要包含在缓存键中的标头”现在分为两部分。如果您使用“缓存策略和源请求策略(推荐)”而不是“旧版缓存设置”,则必须创建新的缓存策略(推荐的重复项)并添加标头(与 CORS-S3Origin 策略中的相同)。 推荐设置 cors-s3origin 缓存优化

  • 就我而言,如果第一次从移动应用程序请求文件,则请求没有标origin头。这就是为什么 S3 返回它们时不带access-control-allow-origin标头,并且它们在不带标头的情况下缓存在 CloudFront 中。由于 CORS 错误(“No 'Access-Control-Allow-Origin'...”),所有带有标头的后续请求origin(当您从 js 发出请求时,浏览器始终添加此标头)都会失败。

  • 可以向从 CloudFront 到 S3 的请求添加自定义标头(源 -> 编辑特定源 -> 添加自定义标头)。如果您不关心用户从何处请求您的文件,您可以origin在此处添加标头并将其设置为任意值。在这种情况下,所有对 S3 的请求都将具有origin标头。 自定义标头

  • 有很多 Clo​​udFront 边缘站点。他们每个人都有自己的缓存。用户将从最近的位置接收文件。这就是为什么某些用户可能成功接收文件,但其他用户却遇到 CORS 错误的原因。

  • CloudFront 响应标头中有一个x-cache标头。该值可以是“Miss from cloudfront”(缓存中没有请求文件)或“Hit from cloudfront”(从缓存返回的文件)。因此,您可以查看您的请求是否是第一个发送到特定边缘位置的请求(如果您想尝试,请在开发工具中禁用浏览器缓存)。但有时它的行为就像随机的),我不知道为什么。

  • 看起来即使是相同的边缘位置也可以为不同的客户端提供不同的缓存。我不知道它是基于什么,但我尝试使用浏览器,Postman和curl进行实验,并得到了下一个结果(我已经尝试了很多次不同的文件和不同的排序 - 来自curl 看不到为浏览器和 Postman 创建的缓存,反之亦然):

    1. 浏览器请求返回“Miss from cloudfront”;
    2. 来自浏览器的请求返回“Hit from cloudfront”;
    3. 来自邮差的请求返回“Hit from cloudfront”;
    4. 来自curl的请求返回“Miss from cloudfront”;
    5. 来自curl的请求返回“Hit from cloudfront”。

由于 AWS 文档对这个问题的了解很差,并且支持人员只是建议阅读文档,因此我不确定我的部分结论。我就是这么想的。