The protocol-relative URL
There's this little trick you can get away with that'll save you some headaches:
<img src="//domain.com/img/logo.png"> |
If the browser is viewing that current page in through HTTPS, then it'll request that asset with the HTTPS protocol, otherwise it'll typically* request it with HTTP. This prevents that awful "This Page Contains Both Secure and Non-Secure Items" error message in IE, keeping all your asset requests within the same protocol.
*Of course, if you're viewing the file locally, it'll try to request the file with the file://
protocol.
We use this trick in the HTML5 Boilerplate for a clever request of jQuery off the Google CDN:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script> <script>!window.jQuery && document.write(unescape('%3Cscript src="/img/spacer.gif"> |
Technically, this is called a "network-path reference" according to RFC 3986. Oh and if you want to be truly correct, you'll use the term "scheme" instead of "protocol" when talking about URLs.
This trick also works fine in CSS:
.omgomg { background: url(//websbestgifs.net/kittyonadolphin.gif); } |
… assuming the site you're pointing to has this asset available on both HTTP and HTTPS.
Caveat: When used on a <link> or @import for a stylesheet, IE7 and IE8 download the file twice. All other uses, however, are just fine.
Thx to miketaylr, ralphholzmann, annevk for smarts on this, and ajaxian, where I think I learned it like 4 years ago? maybe?
Yes of course, wouldn't that be nice… So I worked with the Google Analytics javascript lead developer (God, I love working at google) to see if we could do this.. turns out we can't. There is an edgecase bug in IE6 that causes a dialog to blow up… under some security settings (unsure if they are default) when requesting form the non-'ssl' subdomain. screenshot here. So feel free to take 40 bytes off your GA snippet if you don't care about IE6.. otherwise you're gonna need that ternary operator. :)
The reason this doesn't work in IE6 is that the server is using SNI to deduce what certificate to return. XP (and thus IE6) doesn't support SNI in the HTTPS stack. See for details.
Paul Irish front-end development
Was just thinking.. I wonder if the SPDY protocol will throw everyone for a loop if they're using this technique. Hmm!
I wasn't able to find anything regarding the scheme to be used by SPDY in the Draft ( sites.google.com/a/chromium.org/dev/spdy/spdy-protocol/spdy-protocol-draft1 ), but it is noted that SPDY is meant as a replacement for HTTP.
So in theory, it'll remain HTTP and HTTPS and not be SPDY://?
I just asked Mike Belshe, the lead engineer on SPDY and he said:
Boom.
Shouldn't you use
because the contents of a script that with a src attribute are (at least to my knowledge) interpreted if the script fails to load.
This is an awesome technique to put in use for ecommerce sites that have a "checkout" flow where you start non-secure, switch to secure for payment, and back to non-secure for completion/receipt. Great stuff!
This is so much better than the Google Analytics way:
@Shi Chuan
Indeed it is. Sadly, however, They do use a different subdomain for the SSL requests and you can cause an error dialog in IE6 if you use the protocol-relative URL for google analytics.
I worked for a few hours with an Analytics engineer and Mathias Bynens trying to make that work. Sadly it couldn't.
This is a valuable best practice. The warning about stylesheet double downloads is important, esp. since stylesheets block rendering in many browsers – you don't want that blocking behavior to last any longer than necessary. So use this for everything except stylesheets.
@Steve Souders
IF you're worried about IE. Generally, I optimize maintainability over performance when possible, which in this case would ignore the performance hit for IE. Which is fine with me. Users of sub-par browsers shouldn't expect an optimal experience. Especially with the (anecdotal) observation that IE users tend to be corporate users who have high-speed networks anyway. This is, of course, just a personal preference. Generally I defer any performance related topics to your (Souders) expertise.
Ugh, I wish I had known this previously. Thanks Paul, this is very helpful.
I tried this, but found it a bit annoying since I often work with files locally.
That said, for an http/https switching situation it is an elegant solution to the "this page contains insecure items" malarkey.
We use this all over my current project… did you tell me about it?
How could you not be worried about IE? That means you're not worried about a *HUGE* number of users
@Jason
Um yeah.. whatchu talking about? This is all peachy everywhere with the exception of referencing stylesheets.
So don't use it for that.
Wow, I actually used this technique at work just this morning to clean up some 3rd party code. I learned it years ago, but forgot about it until recently.
This is a great trick, wondering if it could extend to another issue we are having with Google Analytics dropping data. Apparently, if someone sends a link to us such as domain.com and as someone browses our site, they click on www.domain.com – GA drops referral data. I would think that using relative paths is the answer but we still experience dropped data. I wonder if this could work to help keep referral data from being dropped?
I ran into this exact problem the other day where we have a bunch of things using src="/img/spacer.gif">
I use the technique a lot but with only one slash. Is it an error ?
@Jean-Philippe: That’s just a root-relative URL then.
Hi all,
This is a neat trick I just learned about via Paul's Boilerplate. There is one caveat I ran into, however, which is that If I you are using (for example) IE6 in a VM accessing a network share the url will not be resolved. Addresses in this instance are like: "\\tsclient\Y\Documents\Account Services\CLIENTs\etc\etc\something.html".
Not only that but IE6 will hang while trying to resolve until it gives up. I have not tried this with other browsers, as I just use that VM to keep a "real" version of IE6 around for testing. Multiple IE and IETester are nice, but I've been bitten a few times by them.
Not a big deal, but did have me scratching my head wondering what was happening for a while.
Paul, thanks for writing this up. It's a trick I've used for years and I spread it around at each dev shop I work in. Even good developers stare at me in disbelief when I tell them this is possible. I've been meaning to write a blog entry, but…
@Pete B, @Andre Hayter: During development, I add a BASE tag to my pages to give the relative protocol something to hang onto. That way, if you're local and use file://, the base tag's will allow protocol-relative paths to resolve correctly.
Hey Paul,
Can you elaborate on why this doesn't work with Google Analytics? I don't see how it's any different than the CDN.
Thanks,
Nathan
@Paul Irish
@Nathan
Because if you notice in the analytics code, it swaps in a new subdomain if it's in SSL. The regular host doesn't have a legit SSL cert. This doesn't cause a problem for anyone but IE6, who throws up a dialog about insecure assets whatever when you try and do it. Here's a screenshot of that error: paulirish.com/i/1d90.png
So this will automatically insert either https or http into the file name. Do I ever have to change it again or worry about it? For instance, if I put //mydomain.com/images/here.jpg it will convert to either https://mydomain.com/images/here.jpg or mydomain.com/images/here.jpg every time?
Thanks for posting this by the way
was really hoping websbestgifs.net/kittyonadolphin.gif existed.
unescape()
is a lame hack.Thank you. This is very helpful!
october protocol google relative script
for its contents. This is a safe-cache copy of the original web site.