As of Chrome 50, Google have removed the ability for Chrome to do a Geolocation lookup unless the page hosted on a secure origin.
See https://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features
I am building a widget that will be embedded on websites that I do not control, and my widget has some geolocation features. I want to hide geolocation-related UI in my widget if the user is using Chrome and the origin is not considered secure.
How can I detect non-secure origins?
My initial idea was to do something like this:
const geolocationPermitted = () => {
return (!window.chrome) || window.location.protocol == 'https:';
}
But this test fails When developing locally, since I serve the site from localhost over plain http
. This is considered secure by Chrome though, and the function above return false.
I have found that Chrome and Firefox do expose this as a property:
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.
My current test is:
browserHasLocation = () => {
return navigator.geolocation && (!window.chrome || window.isSecureContext);
}
Chrome will have a built in way to check for this, as one can't just check for the origin of the page, because the page could be on https
but inside an iframe that is hosted from an unsecure context etc.
A strong signal that it was a non-secure content issue is to look for the string "Only secure origins are allowed" in the error message.
navigator.geolocation.getCurrentPosition(function(success) {
// Origin IS secure
}, function(failure) {
if(failure.message.indexOf("Only secure origins are allowed") == 0) {
// Origin is NOT secure
}
};
});
This will work on older browsers, as they won't throw an error for an unsecure origin
Information gotten from the Chrome Web Updates page
Another way would be to check the protocol, but as noted above, this is not always reliable, for instance when using iframes etc.
if ( window.location.protocol == 'https:' ) {
// SSL enabled
}
According to Google the following are generally considered "secure".
https://
wss://
file://
chrome-extension://
http://localhost
http://127.0.0.*
*::1.128
So if one is developing on localhost, a check for that would be needed as well, and if using websockets, one would have to check for wss
etc.
Adding to that, the list may not be complete, there could be several other scenarios where the origin is considered secure, that would require additional checks, which is why the first method of using the error callback on getCurrentLocation
should be used.
If developing on localhost, and the script should be used on http(s) protocol only, one could check for both
if (window.location.protocol == 'https:' || ["localhost", "127.0.0.1"].indexOf(location.hostname) !== -1) {...
Or simply comment out the check during development
Use isSecureContext
, for example, console.log(isSecureContext)
.
This is noted by MDN: https://developer.mozilla.org/en-US/docs/Web/API/Window
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.