I ran into an issue where if my Mac denied location sharing, then nothing happens in JS code... this is dangerous, anyway to get around this? If system denies location sharing, I would expect an exception to be thrown
Running macOS Mojave 10.14.6
& tested in Chrome 87.0.4280.88
.
In System Preferences > Security & Privacy
, you can check Enable Location Services
and then check Apps that are allowed. If I EITHER uncheck Enable Location Services
entirely OR keep it checked but uncheck Google Chrome
, then the code quietly fails*, by which I mean nothing is logged to console in the sample code below.
Code:
$("#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")
}
})
Is there a meta way to catch this (e.g., determine whether location has been enabled or not in system preferences from JS) so that something gets logged and I can move onto next steps in code?
*The code quietly fails, but technically the browser has ways of alerting you, but only the FIRST time. So basically, assuming your browser has not blocked the URL and you're on HTTPS (e.g., all the browser conditions are met), the FIRST time you click #btn
, you'll get the native pop up that navigator.geolocation.getCurrentPosition
triggers asking you for permission. Now, even if you click allow, because system preferences disallows it, it won't share, the code doesn't log anything. But at least this first time you get a visual of something happening. On subsequent clicks, truly nothing will happen either on browser or in code. Again I'm more concerned with code, just pointing out that I acknowledge browser shows you things.
HTML5 Geolocation API lets you share your location with your favorite web sites. A JavaScript can capture your latitude and longitude and can be sent to backend web server and do fancy location-aware things like finding local businesses or showing your location on a map.
How does the HTML5 geolocation API work? HTML5 geolocation detects latitude and longitude coordinates by using the device's GPS (if available on the device) or the device's mobile/WIFI signal (if GPS is not available. The mobile/WIFI signals are triangulated to work out the latitude and longitude.
If supported, run the getCurrentPosition() method. If not, display a message to the user. The showError() functiona displays the error message.
How accurate is HTML5 geolocation? HTML5 geolocation is more accurate than other tracking methods, like IP geolocation. However, it is best used for devices that feature a GPS, like a smartphone. While it can work for desktops, HTML5 is best suited for GPS devices.
If your chrome version is 50, then you’ll encounter that HTML5 Geolocation API is not working. In Chrome version 50, HTML5 Geolocation delivered over HTTP no longer supported by Chrome.
Then, use the HTML5 geolocation methods to get the user location. It will be sent to a function that uses Google Geolocation API and shown on the map: If this seems a bit complex, we can analyze the example above in more detail: <div id="canvas" style="width:100%;height:400px;"></div> sets an HTML element to be used as a map canvas.
Go to Safari (top left on Task Bar) -> Preferences… -> Websites - > Location. Select “Deny” for any listed websites you do not want to your geolocation. To prevent all websites from accessing geolocation data in the future, select When visiting other websites: -> Deny.
It is also common for malware to change browser geolocation settings. A VPN will hide your IP address from websites you visit, but this is bypassed if you permit the website to use geolocation. As just noted, your browser should ask for permission before sending this data, but it is possible that it won’t.
On some browsers you can check the permission status without prompting the user like so:
const permissionStatus = await navigator.permissions.query({ name: 'geolocation' })
Compatibility: http://caniuse.com/#feat=permissions-api
Although note that this only indicates the permissions at browser level. Even when this permission is granted, another layer like the OS can still deny it later in the chain.
Given that navigator.geolocation.getCurrentPosition()
always immediately returns with undefined
no matter what, the best you can do to handle these cases is having a timeout
forcing the error callback to be called after a given duration if no response is provided to the browser. Luckily you can do so easily by passing options
as a third argument to the function.
const options = { timeout: 5000 }
navigator.geolocation.getCurrentPosition(successCb, errorCb, options)
In your case:
$("#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")
}
})
Given that the W3C specification details that the browsers must call the callback function on success/error, it is unlikely to be silenced by the browser itself. It is more likely that the OS decides to never respond instead of refusing the access, leaving the function in a pending state indefinitely if no timeout is provided.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With