测试导航器.getUserMedia需要https,没有浏览器用户代理嗅探

Test if navigator.getUserMedia requires https without browser user agent sniffing

本文关键字:浏览器 用户代理 嗅探 https 导航 getUserMedia 需要 测试      更新时间:2023-09-26

我想使用Javascript来确定浏览器是否支持http上的网络摄像头访问(navigator.getUserMedia),如果它不支持,我想将用户重定向到https。然而,如果浏览器不需要https(例如firefox)就支持摄像头访问,我不想将用户重定向到https,我想只使用http来为网站提供服务。我目前的解决方案是移动浏览器的用户代理:

var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;

我目前的解决方案在理论上是行不通的,因为Firefox很可能在未来几年内修补http对网络摄像头访问的支持。

目前我不愿意在所有浏览器上推行https是有原因的,我不会深入讨论,但是我意识到浏览器世界正朝着总有一天需要到处使用https的方向发展。

!!navigator.getUserMedia

这返回true无论我在http或https中运行chrome,我想在当前版本的chrome上运行http时产生一个假值,而不是firefox,我想这样做而不是用户代理嗅探的原因是因为浏览器补丁支持http上的网络摄像头访问,我希望我的代码适应而不需要打补丁。

简而言之,我如何检测在http中支持视频功能的浏览器而不寻找特定的浏览器用户代理?

今天将检测Chrome的https行为,不提示:

(在Chrome中使用fiddle,因为getUserMedia在SO片段中由于某种原因在Chrome中不起作用)

if ('https:' == document.location.protocol) {
  console.log("Page is https.");
} else {
  navigator.mediaDevices.getUserMedia({video: {width: {min: 2, max: 1}}})
  .then(stream => {
    log("Detection failed!");
    stream.getTracks().forEach(t => t.stop());
  })
  .catch(e => {
    switch (e.name) {
      case "NotSupportedError":
      case "NotAllowedError":
      case "SecurityError":
        console.log("getUserMedia in http is disallowed");
        break;
      case "OverconstrainedError":
      default:
        console.log("getUserMedia in http is allowed");
        break;
    }
  });
}

这是有效的,因为Chrome今天失败的"NotSupportedError"在https 之前它考虑约束。我们传递了不可能的约束,所以在允许http的情况下,我们用"OverconstrainedError"代替失败,所以无论哪种方式,都不会向用户显示提示符。

你会注意到我有点保值,因为"NotSupportedError"实际上不是根据规范的有效错误。我认为一旦Chrome更新遵循规范,它应该失败与"SecurityError"而不是"NotSupportedError",但我不确定。有可能它会首先考虑约束,在这种情况下,这个测试可能会停止工作。

我想我找到了一个解决方案,我已经在safari, firefox和chrome上进行了测试:

if(navigator.mediaDevices){
  navigator.mediaDevices.getUserMedia({video:true}).then(function(){
    //firefox, chrome in https
    alert('success!'); 
  }, function(){
    //chrome in http
    alert('failure!'); 
  });
} else {
  //safari, ie
  alert('not supported');
}

这确实弹出一个权限泡沫运行时,这是不可取的,我想找到一个解决方案,不打扰用户在它的检测过程。