Safari 12.1似乎已停止记住跨域iframe的getUserMedia(在这种情况下为麦克风)权限。
给出两个站点的简化示例:
域A:
<!DOCTYPE html>
<html>
<head></head>
<body>
<button onclick="triggerUserMedia()">Get User Media</button>
<script>
function triggerUserMedia(){
const constraints = { audio: true, video: false };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
console.log('got stream');
})
.catch(function(err) {
console.log('couldn\'t get the stream');
});
}
</script>
</body>
</html>
域B:
<!DOCTYPE html>
<html style="height:100%">
<head></head>
<body>
<iframe src="https://domain-a/index.html" allow="microphone"></iframe>
</body>
</html>
在Safari 1.2.1之前的版本以及当前的Chrome等版本中,如果将其嵌入到域B中,则多次按下按钮会导致一个“允许“域A”使用您的麦克风?”,仅在第一个按下。
但是,现在每次按下按钮都会弹出权限弹出窗口。
有人知道在Safari 12.1中有哪些特别更改是什么导致此行为更改的吗? (这是新的Webkit安全限制吗?)
如何做才能确保仅像以前那样只请求一次许可?
(我们在旨在嵌入不同站点的项目中多次调用getUserMedia,因此对用户体验产生了重大影响)
答案 0 :(得分:1)
即使对于相同的域iframe,我也遇到相同的问题-仅在iframe内部请求getUserMedia
总是会请求权限。
即使在跨域环境中,我也发现了一个丑陋的解决方法:如果您至少一次在“主机”页面上请求权限,它将开始在iframe中运行。它要求您有一些“主机页面”脚本,可以与iframe通信(通过窗口消息,以避免跨域问题),但是它可以工作。
即使使用我的解决方法,另一个奇怪的行为是,enumerateDevices
如果先在主机页上然后在iframe内请求权限,则不会返回有效的设备名称。因此,完整的解决方法(如果需要枚举)将具有2个权限提示:
getUserMedia
调用时显示提示)答案 1 :(得分:0)
我无法回答浏览器供应商在每次请求媒体流时都会使iframe getUserMedia请求再次提示获得许可的情况,但是我们发现解决方案是使用父mediaDevices单例请求流。
function getRootWindow(window) {
if (window.parent === window) {
return window;
}
return getRootWindow(window.parent);
}
getRootWindow(window).navigator.mediaDevices.getUserMedia().then(...);
我们已经在iOS,FF,Chrome,Safari和Safari上对此进行了测试,并且在授予权限之后,对媒体设备的后续请求也可以正常运行。从iFrames DOM调用此操作会导致它在每次请求时发出提示。