【问题标题】:Frontend JavaScript request gets 302-redirected but ultimately fails前端 JavaScript 请求被 302 重定向但最终失败
【发布时间】:2020-10-15 10:33:30
【问题描述】:

我正在尝试为播客网络创建音频可视化,使用带有 createMediaElementSource() 的 Web 音频 API,与模型 explained in this tutorial 非常相似。到目前为止,我已经让它在 Chrome 和 you can see it here 中正常工作(注意:点击红色框启动它)。

更新:根据 cmets 中的讨论,现在很明显问题的发生是因为请求通过 302 重定向重定向到另一个 URL。


然而,Safari 拒绝工作,尽管它显示了正在播放的曲目,但它没有输出声音,也没有产生可视化效果。我相信这与我请求音频的服务器的 CORS 策略有关,因为我也尝试过使用 this audio source 并且它在所有浏览器中都很好用。我怀疑这是由于网络音频 API 的this standard 引起的问题。

它只发生在 safari 中的事实让我祈祷在他们的 CORS 策略中我端或服务器主机端有一些简单的语法解决方案来让它发挥作用。我希望有人能准确指出导致此问题的标头请求/响应中出了什么问题。如果我需要提供更多信息,请告诉我。我在下面留下了我的 AudioContext 代码的简化版本,以防出现问题。

//definitions
var url='https://rss.art19.com/episodes/72a3bc7e-118a-4171-8be4-125913860ef7.mp3';
//in safari it works with the link below, but not with any art19 link such as the one above.
//https://s3-us-west-2.amazonaws.com/s.cdpn.io/858/outfoxing.mp3
var audiotag=document.querySelector('audio');
var AudioContext = window.AudioContext || window.webkitAudioContext;
var context;
var statcontext;
var analyser;
var source;
var loopf;

//on load:
context=new AudioContext();
audiotag.crossOrigin="anonymous";
audiotag.preload="none";
audiotag.src=url;
source=context.createMediaElementSource(audiotag);
analyser=context.createAnalyser();
source.connect(analyser);
analyser.connect(context.destination);
analyser.smoothingTimeConstant=0.85
analyser.fftSize = 16384;

//later, on user input(clicking on red bar):
var bufferLength = analyser.frequencyBinCount;
var dataArray = new Uint8Array(bufferLength);
function updateDisplay() {
  loopf=requestAnimationFrame(updateDisplay);
  analyser.getByteFrequencyData(dataArray);
  draw(dataArray.slice(100,150),-100,100);
}
context.resume();
audiotag.play();
updateDisplay();

【问题讨论】:

  • 浏览器在 devtools 控制台中记录的确切错误消息是什么?
  • 控制台中没有显示错误消息!曲目播放时只是静音音频,没有输出到音频上下文可视化
  • 还有一个更新:我正在浏览您的个人资料并看到您关于使用 cors 代理的帖子,因此我通过将我的 URL 源设置为以下内容在公共演示中进行了尝试:cors-anywhere.herokuapp.com/https://rss.art19.com/episodes/… 和有效!这表明问题是什么——CORS 是否仍然被排除在外?
  • 关于非代理解决方案的任何想法?我链接了 web 音频 API 的 w3 标准部分,我认为它决定了我所看到的行为,如果源元素“已使用 HTMLMediaElement 创建,其执行提取算法 [FETCH] 标记为资源作为 CORS-cross-origin。”
  • 所以我可以与我发出请求的服务器主机通信,因为我的客户通过托管音频链接为 CMS 和 RSS 付费;我可以要求他们更改标题或 CORS 政策吗?

标签: safari xmlhttprequest cors web-audio-api audiocontext


【解决方案1】:

简短回答:向您的请求发送 302 响应的服务维护人员应更新其后端配置,以便将 Access-Control-Allow-Origin 标头添加到 302 响应(以及任何其他 3xx 重定向响应) -不仅仅是200 OK 回复。

如果你不能让他们这样做,那么基本上你只有另外两个选择:

  1. 更改您的前端代码以通过 CORS 代理发出请求;否则
  2. 根本不要从您的前端代码发出请求,而是完全从您的后端服务器端代码发出请求(same-origin policy 不适用)。

说明

发生了什么:

  1. 您的前端代码向https://rss.art19.com/episodes/….mp3 URL 发出请求。

  2. https://rss.art19.com 服务器使用带有 Location: https://content.production.cdn.art19.com/…episodes/….mp3 标头的 302 重定向响应进行回复。

  3. 浏览器收到302 响应并检查响应标头以查看是否有Access-Control-Allow-Origin 标头。如果没有,浏览器会阻止您的代码访问来自 https://content.production.cdn.art19.com/….mp3 重定向 URL 的响应。相反,浏览器会停止并抛出异常。

您有时可以通过获取重定向 URL 并将其用作前端代码中的请求 URL 来解决此问题。例如,不要在代码中使用https://rss.art19.com/episodes/….mp3,而是使用https://content.production.cdn.art19.com/…episodes/….mp3——因为来自该URL的200 OK响应确实包含Access-Control-Allow-Origin标头。

但在实践中的许多或大多数情况下,该策略行不通——因为先发制人地识别重定向 URL 是不可行的。

请注意,浏览器有意不将重定向 URL 暴露给前端代码。因此,从前端代码中以编程方式获取重定向 URL 并使用它执行另一个请求是不可能的。

【讨论】:

  • 如果你像浏览器一样发送一个 Origin 标头,你会得到你所期望的 Access-Control-Allow-Origin。
猜你喜欢
  • 2015-11-26
  • 2017-02-14
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 1970-01-01
  • 2014-08-22
  • 1970-01-01
  • 2022-12-16
相关资源
最近更新 更多