我如何检测 Chrome 是否认为当前页面是安全来源?

How can I detect if Chrome thinks the current page is a secure origin?

自 Chrome 50 起,Google 已删除 Chrome 进行地理位置查找的功能,除非页面托管在安全源上。

https://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features

我正在构建一个小部件,它将嵌入到我无法控制的网站上,并且我的小部件具有一些地理定位功能。如果用户正在使用 Chrome 并且来源不被认为是安全的,我想在我的小部件中隐藏与地理位置相关的 UI。

如何检测不安全的来源?

更新

我最初的想法是做这样的事情:

const geolocationPermitted = () => {
  return (!window.chrome) || window.location.protocol == 'https:';
}

但是在本地开发时这个测试失败了,因为我通过普通 http 从本地主机提供站点。这被 Chrome 认为是安全的,而上面的函数 return false.

Chrome 将有一个内置的方法来检查这一点,因为不能只检查页面的来源,因为页面可能在 https 但在 iframe 中从不安全的环境等托管的

这是一个不安全内容问题的强烈信号是在错误消息中查找字符串 "Only secure origins are allowed"

navigator.geolocation.getCurrentPosition(function(success) {
      // Origin IS secure
}, function(failure) {
    if(failure.message.indexOf("Only secure origins are allowed") == 0) {
      // Origin is NOT secure
    }
  };
});

这将适用于旧版浏览器,因为它们不会针对不安全来源抛出错误

Chrome Web Updates page

获得的信息

另一种方法是检查协议,但如上所述,这并不总是可靠的,例如在使用 iframe 等时。

if ( window.location.protocol == 'https:' ) {
    // SSL enabled
}

根据Google一般认为以下是"secure".

  • https://
  • wss://
  • file://
  • chrome-extension://
  • http://localhost
  • http://127.0.0.*
  • *::1.128

因此,如果在本地主机上进行开发,则还需要对其进行检查,如果使用 websockets,则必须检查 wss 等。

除此之外,列表可能不完整,可能还有其他几种情况,其中来源被认为是安全的,这将需要额外的检查,这就是为什么第一种方法在 [=22 上使用错误回调=] 应该被使用。

如果在本地主机上开发,脚本应该只在 http(s) 协议上使用,可以检查两者

if (window.location.protocol == 'https:' || ["localhost", "127.0.0.1"].indexOf(location.hostname) !== -1) {...

或者在开发过程中简单地注释掉检查

我发现 Chrome 和 Firefox 确实将其公开为 属性:

https://developer.mozilla.org/en-US/docs/Web/API/Window/isSecureContext

The window.isSecureContext read-only property indicates whether a context is capable of using features that require secure contexts.

我目前的测试是:

browserHasLocation = () => {
    return navigator.geolocation && (!window.chrome || window.isSecureContext);
}