jam*_*mes 5 html javascript geolocation
我遇到了一个问题,如果我的 Mac 拒绝位置共享,那么 JS 代码中什么也不会发生……这很危险,无论如何要解决这个问题?如果系统拒绝位置共享,我希望抛出异常
运行macOS Mojave 10.14.6和测试中Chrome 87.0.4280.88。
在 中System Preferences > Security & Privacy,您可以检查Enable Location Services并检查允许的应用程序。如果我要么Enable Location Services完全取消选中Google Chrome,要么保持选中但取消选中,那么代码会悄悄地失败*,我的意思是在下面的示例代码中没有任何内容记录到控制台。
代码:
$("#btn").click(function(e){
e.preventDefault();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
# success
function(location) {
console.log("GPS coordinates retrieved")
},
# failure
function(error) {
console.log(error.message)
}
)
} else {
console.log("GPS not supported by browser")
}
})
Run Code Online (Sandbox Code Playgroud)
有没有一种元方法来捕捉这个(例如,确定是否在来自 JS 的系统首选项中启用了位置),以便记录某些内容并且我可以继续代码中的下一步?
*代码悄悄地失败了,但从技术上讲,浏览器有提醒你的方法,但只有第一次。所以基本上,假设您的浏览器没有阻止 URL 并且您使用 HTTPS(例如,满足所有浏览器条件),您第一次单击 时#btn,您将获得navigator.geolocation.getCurrentPosition触发请求许可的本机弹出窗口。现在,即使您单击允许,因为系统首选项不允许它,它也不会共享,代码不会记录任何内容。但至少这是你第一次看到正在发生的事情。在随后的点击中,无论是在浏览器还是在代码中都不会发生任何事情。我再次更关心代码,只是指出我承认浏览器向您展示了一些东西。
在某些浏览器上,您可以在不提示用户的情况下检查权限状态,如下所示:
const permissionStatus = await navigator.permissions.query({ name: 'geolocation' })
Run Code Online (Sandbox Code Playgroud)
尽管请注意,这仅表示浏览器级别的权限。即使授予此权限,其他层(如操作系统)仍然可以在链中稍后拒绝它。
鉴于无论如何navigator.geolocation.getCurrentPosition() 总是立即返回,undefined处理这些情况的最佳方法是timeout如果没有向浏览器提供响应,则强制在给定持续时间后调用错误回调。幸运的是,您可以通过将options第三个参数传递给函数来轻松实现。
const options = { timeout: 5000 }
navigator.geolocation.getCurrentPosition(successCb, errorCb, options)
Run Code Online (Sandbox Code Playgroud)
在你的情况下:
$("#btn").click(function(e){
e.preventDefault()
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
// success
function(location) {
console.log("GPS coordinates retrieved")
},
// failure
function(error) {
console.log(error.message)
},
{
timeout: 5000 // ms
}
)
} else {
console.log("GPS not supported by browser")
}
})
Run Code Online (Sandbox Code Playgroud)
鉴于W3C 规范详细说明浏览器必须在成功/错误时调用回调函数,浏览器本身不太可能使其静音。更有可能的是,操作系统决定从不响应,而不是拒绝访问,如果没有提供超时,函数就会无限期地处于挂起状态。