自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:';
}
但是这个测试失败在本地开发时,因为我从localhost通过普通http
提供站点。 Chrome认为这是安全的,上面的函数返回false。
答案 0 :(得分:4)
我发现Chrome和Firefox确实将其公开为属性:
https://developer.mozilla.org/en-US/docs/Web/API/Window/isSecureContext
window.isSecureContext
只读属性指示上下文是否能够使用需要安全上下文的功能。
我目前的测试是:
browserHasLocation = () => {
return navigator.geolocation && (!window.chrome || window.isSecureContext);
}
答案 1 :(得分:1)
Chrome会有一种内置方式来检查这一点,因为人们不能只检查页面的来源,因为该页面可能在https
上,但在一个由不安全托管的iframe中背景等。
这是一个非安全内容问题的强烈信号是在错误消息中查找字符串“仅允许安全来源”。
navigator.geolocation.getCurrentPosition(function(success) {
// Origin IS secure
}, function(failure) {
if(failure.message.indexOf("Only secure origins are allowed") == 0) {
// Origin is NOT secure
}
};
});
这适用于较旧的浏览器,因为它们不会为不安全的来源引发错误
的信息另一种方法是检查协议,但如上所述,这并不总是可靠的,例如在使用iframe等时。
if ( window.location.protocol == 'https:' ) {
// SSL enabled
}
据谷歌称,以下通常被认为是“安全的”。
https://
wss://
file://
chrome-extension://
http://localhost
http://127.0.0.*
*::1.128
因此,如果正在开发localhost,那么也需要对其进行检查,如果使用websockets,则必须检查wss
等。
除此之外,列表可能不完整,可能还有其他几种情况,其中原点被认为是安全的,这需要额外的检查,这就是为什么在getCurrentLocation
上使用错误回调的第一种方法应该使用。
如果在localhost上进行开发,并且该脚本只应在http(s)协议上使用,则可以检查两者
if (window.location.protocol == 'https:' || ["localhost", "127.0.0.1"].indexOf(location.hostname) !== -1) {...
或者只是在开发期间注释掉检查