A while ago I created the most useful web page I’ve ever written; an extremely basic page to list the bus arrival times, based on your current location anywhere in London!
I have used this page several times a day on an almost daily basis since I created it, as does my wife; every morning we need to know when the next bus will arrive near our house in order to know when to rush out with our children to take them to school.
I used it every morning to check if I needed to rush out the door to catch the rare “express” bus that would get me to the tube much quicker than the usual one.
I discovered just how useful it is whilst in a pub, deciding whether I had time for another drink before heading home; a quick glance at my phone and I could find out that the next bus home wasn’t for 20 minutes – plenty of time!
However, recently it stopped working for me. It still worked just fine on my wife’s iPhone (and hence Safari), but not on my Nexus (Chrome). It works on my laptop too, or at least appeared to.
So what’s going on?
Let’s review a pertinent chunk of the code:
$(document).ready(function() {
// get lat long
if (navigator.geolocation){
navigator.geolocation.getCurrentPosition(function (position) {
getStopListingForLocation(position.coords.latitude, position.coords.longitude);
});
} else {
alert('could not get your location');
}
});
This is how I work out your current location, which is then used to work out a bounding rectangle to search the TFL (Transport For London) API for bus stops. It seems likely that this is the bit which wasn’t working for me.
In order to work out what’s going on, I had to plug my phone in to my laptop, open up Chrome dev tools, and enable my phone via “chrome://inspect/”. This meant that I was then able to see a debug console on my laptop which when hitting my bus listing page on my phone displayed the warning:
getCurrentPosition() and watchPosition() are deprecated for insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
If you follow that URL you’ll be taken to a page entitled:
Deprecating Powerful Features on Insecure Origins
The powerful features are currently listed as:
- Geolocation
- Device motion / orientation
- EME (I’m guessing this is Encrypted Media Extensions)
- getUserMedia
- AppCache
Ahhhh – that would explain why it didn’t work on my phone but did on the iPhone still.
Fixing “deprecated for insecure origins”
AppHarbor
If I can get the web page served over HTTPS this would remove the warning and allow the location JavaScript to execute.
Given I had used AppHarbor as my free host, the URL of the web page was “http://rposbo.apphb.com” – notice that’s not over HTTPS. Unfortunately AppHarbor doesn’t have a shared SSL cert for the “apphb.com” domain, so I couldn’t just change the URL to start with “https”
If I wanted to get it over HTTPS I’d have to pay:
Adding a certificate costs $10/month, unless the application is on a paid subscription.
Booo! As such, I decided to use one of my other free web hosts of choice; Azure.
Azure
Azure does have a shared SSL cert for their “azurewebsites.net” domain, which means even your free website can be over HTTPS if you’re happy with the domain being “azurewebsites.net”.
I logged into the Azure portal and selected “New > Web + Mobile > Web App”
Once Azure had done its setup, I selected the new web app and went to “Settings > Publishing > Deployment Source”.
Since the Bus web page is in a repo on github I just selected that repo from the github connector and let Azure clone and deploy it to my new web app.
A few moments later and I had a shiny new, secure, home for my little web app: https://mybus.azurewebsites.net!
The moment of truth
So – does it now work?
Sure does!
Summary
If you’re relying on getCurrentPosition()
and serve your page to Chrome users over HTTP only, then you need to move over to an HTTPS endpoint.
There are plenty of options for this, especially since LetsEncrypt.org is now out of beta.