前端 JavaScript 请求被 302 重定向但最终失败
Frontend JavaScript request gets 302-redirected but ultimately fails
我正在尝试为播客网络创建音频可视化,使用网络音频 API 和 createMediaElementSource() 与模型 explained in this tutorial. So far I've gotten it to work fine in Chrome, and you can see it here 非常相似(注意:单击红色框启动它)。
更新:根据评论中的讨论,现在很明显问题的发生是因为请求通过 302 重定向到另一个 URL重定向。
然而,Safari 拒绝工作,尽管它显示曲目正在播放,但没有输出声音也没有产生可视化。我相信这与我请求音频的服务器的 CORS 策略有关,因为我也尝试使用网络音频 API.
的 this audio source and it works great in all browsers. My suspicion is it's an issue arising due to this standard
它只发生在 safari 中这一事实让我祈祷在我端或服务器主机端在他们的 CORS 策略中有一些简单的语法解决方案来实现它。我希望有人可以准确地指出 header requests/responses 中出现的问题 。如果我需要提供更多信息,请告诉我。我在下面留下了我的 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();
简短回答:发送 302
响应您的请求的服务的维护者应该更新他们的后端配置,以便将 Access-Control-Allow-Origin
header 添加到 302
响应(以及任何其他 3xx
重定向响应)——不仅仅是 200
OK 响应。
如果你不能让他们这样做,那么基本上你只有另外两个选择:
- 更改您的前端代码以通过 CORS 代理发出请求;否则
- 根本不要从您的前端代码发出请求,而是完全从您的后端 server-side 代码发出请求(same-origin policy 不适用)。
说明
事情是这样的:
您的前端代码向 https://rss.art19.com/episodes/….mp3
URL.
发出请求
https://rss.art19.com
服务器回复 302
重定向响应,该响应具有 Location: https://content.production.cdn.art19.com/…episodes/….mp3
header.
浏览器收到 302
响应并检查响应 header 以查看是否有 Access-Control-Allow-Origin
header。如果没有,浏览器会阻止您的代码访问来自 https://content.production.cdn.art19.com/….mp3
重定向 URL 的响应。相反,浏览器将停止并抛出异常。
您有时可以通过采用重定向 URL 并将其用作前端代码中的请求 URL 来解决此问题。例如,不要在你的代码中使用 https://rss.art19.com/episodes/….mp3
,而是使用 https://content.production.cdn.art19.com/…episodes/….mp3
——因为来自它的 200 OK
响应包括 Access-Control-Allow-Origin
header).
但在实践中的许多或大多数情况下,该策略将行不通 — 因为抢先确定重定向 URL 是什么是不可行的。
注意:按照设计,浏览器不会将重定向暴露给前端代码。因此,不可能从前端代码以编程方式获取重定向 URL 并使用它执行另一个请求。
我正在尝试为播客网络创建音频可视化,使用网络音频 API 和 createMediaElementSource() 与模型 explained in this tutorial. So far I've gotten it to work fine in Chrome, and you can see it here 非常相似(注意:单击红色框启动它)。
更新:根据评论中的讨论,现在很明显问题的发生是因为请求通过 302 重定向到另一个 URL重定向。
然而,Safari 拒绝工作,尽管它显示曲目正在播放,但没有输出声音也没有产生可视化。我相信这与我请求音频的服务器的 CORS 策略有关,因为我也尝试使用网络音频 API.
的 this audio source and it works great in all browsers. My suspicion is it's an issue arising due to this standard它只发生在 safari 中这一事实让我祈祷在我端或服务器主机端在他们的 CORS 策略中有一些简单的语法解决方案来实现它。我希望有人可以准确地指出 header requests/responses 中出现的问题 。如果我需要提供更多信息,请告诉我。我在下面留下了我的 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();
简短回答:发送 302
响应您的请求的服务的维护者应该更新他们的后端配置,以便将 Access-Control-Allow-Origin
header 添加到 302
响应(以及任何其他 3xx
重定向响应)——不仅仅是 200
OK 响应。
如果你不能让他们这样做,那么基本上你只有另外两个选择:
- 更改您的前端代码以通过 CORS 代理发出请求;否则
- 根本不要从您的前端代码发出请求,而是完全从您的后端 server-side 代码发出请求(same-origin policy 不适用)。
说明
事情是这样的:
您的前端代码向
发出请求https://rss.art19.com/episodes/….mp3
URL.https://rss.art19.com
服务器回复302
重定向响应,该响应具有Location: https://content.production.cdn.art19.com/…episodes/….mp3
header.浏览器收到
302
响应并检查响应 header 以查看是否有Access-Control-Allow-Origin
header。如果没有,浏览器会阻止您的代码访问来自https://content.production.cdn.art19.com/….mp3
重定向 URL 的响应。相反,浏览器将停止并抛出异常。
您有时可以通过采用重定向 URL 并将其用作前端代码中的请求 URL 来解决此问题。例如,不要在你的代码中使用 https://rss.art19.com/episodes/….mp3
,而是使用 https://content.production.cdn.art19.com/…episodes/….mp3
——因为来自它的 200 OK
响应包括 Access-Control-Allow-Origin
header).
但在实践中的许多或大多数情况下,该策略将行不通 — 因为抢先确定重定向 URL 是什么是不可行的。
注意:按照设计,浏览器不会将重定向暴露给前端代码。因此,不可能从前端代码以编程方式获取重定向 URL 并使用它执行另一个请求。