由于 CORS 访问限制,MediaElementAudioSource 输出零

Posted

技术标签:

【中文标题】由于 CORS 访问限制,MediaElementAudioSource 输出零【英文标题】:MediaElementAudioSource outputs zeroes due to CORS access restrictions 【发布时间】:2017-02-10 11:07:30 【问题描述】:

我有一个指向亚马逊 s3 上的 mp3 的链接(aws mp3 设置为公开) 音频播放器运行良好。

但是当我尝试制作可视化器时,一旦我连接到音频播放器,就会出现 CORS 错误。我不明白为什么会这样。

我一直使用 analyzerNode 的 MDN 示例作为基础 https://developer.mozilla.org/en/docs/Web/API/AnalyserNode

<audio id="audio-player-console" src="$AWS_songUrl" autoplay>
    <p>Your browser does not support this audio player </p>
</audio>

澄清一下,只要不尝试连接分析数据,音频播放器就可以毫无问题地运行曲目。

如果我将 crossorigin="anonymous" 添加到音频标签,那么我什么也得不到,音频播放器也不会播放曲目

<audio id="audio-player-console" src="$AWS_songUrl" crossorigin="anonymous" autoplay>
    <p>Your browser does not support this audio player </p>
</audio>

设置“公开”后我的 AWS CORS 配置

 <?xml version="1.0" encoding="UTF-8"?>
 <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

这是我尝试将音频标签连接到可视化器的音频上下文的地方,这是它开始未能通过 CORS 检查的地方

canvasCtx = visualizerCanvas.getContext("2d")
audioCtx =  new (window.AudioContext  || window.webkitAudioContext)()
var audiosrc = audioCtx.createMediaElementSource(aPlayer)
var analyser = audioCtx.createAnalyser()
audioSrc.connect(analyser)
analyser.fftSize = 2048
var bufferLength = analyser.frequencyBinCount
var dataArray = new Uint8Array(bufferLength)
analyser.getByteTimeDomainData(dataArray)

我只是不知道我能做什么。我已将 AWS 配置设置为公开,允许所有来源和所有标头

【问题讨论】:

我一直有同样的问题。几个月来,我花了很多时间试图弄清楚这一点。我问了两个 SO 问题(每个都收到了赞成票),我刚刚在 askubuntu.com 上问了一个问题。我希望我能尽快找到一个解决方案,然后我可以在这里重新发布。 我认为问题与可视化器节点在音频标签已经完成后导致第二次 cors 检查有关。此时文件位于不同的位置,因此无法通过 cors 检查。但我不太确定这一点。我通过完全放弃音频标签并且只使用完整播放器的音频上下文对象来解决它:joegrundman.github.io/gplayer-react/ 【参考方案1】:

经过数小时的研究和实验,我最终弄清楚了该怎么做。在撰写本文时,在线可用的文档很少,显示如何执行此操作。我希望人们会觉得这很有帮助。

了解 CORS:

CORS 是 Cross Origin Resoruce Sharing 的首字母缩写。 CORS 是用于在不同域之间共享/访问信息的新标准。 CORS 基本上是一种使用服务器标头告诉浏览器是否允许访问或与另一台服务器上的特定文件交互的方法。虽然您可以加载大多数内容而无需担心 CORS(如图像、音频、视频甚至其他网页),但与这些元素的交互需要服务器的特殊许可。就我而言,我试图从另一台服务器上的音频文件中读取频率。在这种情况下,我试图访问需要服务器上特殊标头授权的信息。

浏览器支持非常好,但如果您支持旧版浏览器,您可能希望在此处查看支持表 (http://caniuse.com/#search=cors)

我做了什么:

启用 .htaccess 的使用(我认为您可以使用 apache2.conf 或 000-default.conf 完成同样的事情,但 .htaccess 文件更容易编辑和维护)。这些文件用于设置 apache 的标头和设置。我通过转到 /etc/apache2/ 并编辑了 apache2.conf 启用了 .htaccess 文件的使用。确保您的条目与以下内容匹配:

<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>

我在 .htaccess 文件中设置了标题以允许从 Codepen 进行访问。在与您要共享的文件相同的目录中创建一个 .htaccess 文件。您只想分享您必须分享的内容,否则您可能会产生安全风险。在您的 .htaccess 文件中输入:

Header set Access-Control-Allow-Origin: "http://websiteWantingToAccessYourFile.com".

保存您的文件。 使用此命令重新启动 Apache sudo service apache2 restart。如果有提示,请输入密码。 通过音频,我添加了crossorigin="anonymous" 属性。您可以在此处 (https://developer.mozilla.org/en-US/docs/Web/html/CORS_settings_attributes) 阅读有关 CORS 设置(跨域)的更多信息,我想您可以使用 ajax 和 xhr 请求进行设置。 不同版本的 apache 可能有不同的文件名或标准。检查以确保这对于您的版本是正确的。我在我的 Ubuntu 服务器上运行 Apache 2.4.18。

请告诉我这是否可以改进。我花了很多时间来理解这一点,但我不是专家。在 cmets 中发布您的问题或建议。 :)

【讨论】:

能否贴出设置 crossorigin="anonymous" 属性的代码? 试试&lt;audio src='mySrc' crossorigin="anonymous"&gt;&lt;/audio&gt; @RyanGross 我之前尝试过,但忘记在我的回答中提及它。音频已加载并播放,但分析仪被拒绝访问频率数据。 @jylopez 见上面的评论。

以上是关于由于 CORS 访问限制,MediaElementAudioSource 输出零的主要内容,如果未能解决你的问题,请参考以下文章

由于 CORS 访问限制本地 mp3 文件,MediaElementAudioSource 输出零

跨域访问CORS探究

AJAX跨域调用相关知识-CORS和JSONP

由于 CORS 限制,无法使用 firebase 在本地进行测试

如何使用 CORS 限制 AWS S3 访问?

Java服务端用CORS方法解决浏览器跨域问题