If you’ve looked at any web page code in the last few years you’ve probably seen something like this around.
<link href=’//fonts.googleapis.com/css?family=Open+Sans’ rel=’stylesheet’ type=’text/css’>
For some time, I didn’t understand why there wasn’t a HTTP or HTTPS at the front of those URL? In fact, I thought it was an error.
It wasn’t until one of my clients requested that I install a SSL certificate on their site, and ended up with mixed content warnings everywhere, that I stumbled upon the importance of using what are called “protocol relative URLs”.
When it comes to converting a web site to use HTTPS connections, one of the more annoying tasks is to ensure that those pages make no references to unsecure HTTP connections.
If they do, then the browser will pop up alarming messages about mixing secure and insecure content like the message below.
In this age of heightened online security concerns, this not only confuses site visitors but generally discourages them from continuing to use your site.
A Possible But Weak Solution
One solution is to use relative URLs. Relative URLs omit the protocol (among other things) and specifying the path to the asset/resource “relative” to the existing page. An image on a web page that uses a relative URL might look like this:
<img src=’/images/woeiyu.jpg’ />
The image will display without warning on either HTTP or HTTPS pages.
But what if you need to pull resources from, say, another web site where a relative URL won’t work. For example, if I wanted to load jQuery from the jQuery content delivery network (CDN) I might use this code:
If this line appears in an HTTPS page, the mixed content warning will appear because the URL starts with http which says to use an insecure connection.
A Great Solution
An elegant solution was to implement protocol relative URLs.
Simply put, a protocol-relative URL (PRURL) automatically uses either HTTP or HTTPS depending on the user’s browser settings. So when a URL’s protocol is omitted, the browser uses the underlying document’s protocol instead.
Therefore, to load jQuery using a PRURL I would have a line that looks something like this:
Notice the protocol – the http or the https – is missing.
So, on a page using secure connections (an HTTPS page), this connection to the jQuery CDN will be a secure one whereas on a page using insecure connections (an HTTP page) the connection will be an insecure one.
However, there are some caveats.
- Protocol relative URLs only work for pages in a modern web browser. If you use them within HTML emails, some email clients like Outlook assume you are referring the local machine and mistake them as the “file://” protocol instead of “http://” or “https://” protocols.
- IE6 does not know how to handle this. If you care about supporting Internet Explorer 6 then you shouldn’t use these; although if you are still using IE6, you got more serious things to worry about.
- Another thorny issue is that both Internet Explorer 7 and 8 will download the resource twice. Once using an unsecure connection and once using a secure connection which will slow down your web site, particularly if you have a lot of PRURLs.
- A slightly more serious issue, is if you use protocol relative URL on your secure page to an external site that does not support the secure HTTPS, you’ll trigger a browser warning similar to one shown below from Firefox.
In this case, then an absolute URL using the http protocol is your only choice.
So in summary, there is no cure-all when dealing with mix protocol in a page. But with protocol relative URLs, you are one very big step closer.