When building a web site with HTTPS pages, one of the annoying tasks is to ensure that those pages make no references to HTTP resources. If they do, then Internet Explorer will pop up alarming messages about mixing secure and insecure content, and do you want to display the insecure content. This confuses users and generally discourages them from continuing to use your site.
To fix the problem, all URLs on the page must use HTTPS. Web sites these days are built from reusable components, some of which may be used on both HTTP and HTTPS pages. How to make the URLs correct for both?
Relative URLs are the answer. Typically, relative URLs omit the hostname, specifying the full path to the resource, or perhaps just a single path component:
<img src='/pix/smiley.jpg' />
<img src='smiley.jpg' />
Either of these images will display without warning on either HTTP or HTTPS pages. Since the host name is omitted, it uses the host name from the page being displayed. But these URLs also omit the protocol scheme, so the protocol is taken from the base URL also. On an HTTP page, the images will be requested using HTTP, on an HTPPS page, they will use HTTPS. That’s why there’s no warning, because there’s no mixing of secure and insecure content.
But what if you need to pull resources from another site? For example, a CDN (content delivery network)? Here the problem seems to be thornier:
<img src='http://fast.cdn.net/pix/smiley.jpg' />
If this reference appears in an HTTPS page, the mixed content warning will appear. How to craft a reference that works for both? The answer is again relative URLs, but using a more obscure syntax:
<img src='//fast.cdn.net/pix/smiley.jpg' />
Here, we’ve left off the protocol scheme, but included a host name. In this case, the protocol scheme from the displayed page will be used, but against the host in the URL. The relative URL system is still in play here: omitted portions of the URL at the beginning are taken from the base page, and the relative URL takes over whereever it starts. On an HTTPS page, this will be an HTTPS request to the CDN, on an HTTP page, it will be an HTTP request.
You have to be careful to only use this syntax in pages destined for browsers. If you put it in an email, there will be no base page URL to use in resolving the relative URL. In Outlook at least, this URL will be interpreted as a Windows network file, not what you intended.
BTW: when trying to get rid of the mixed secure and insecure content warning, you really have to fix up every URL, even if it doesn’t seem like it’s being used for anything. Flash content? There’s a macromedia.com URL in there in the codebase attribute:
width="600" height="400"> ... </object>
Making it scheme-relative as shown will also prevent warnings.
BTW, do you know in which HTML version did this appear?
Also, Google Analytics provides a secure reference to their .js file as well.
Would love to see it working. Do you have it running somewhere?
I know this syntax works in IE6, IE7, FF2, and Safari 2 and 3. I don't know of any browsers in which it doesn't work.
I think this is not a case of new syntax, but of a specialized and little-used syntax.
complete pain in the butt.
I wish most of the web developers who use https should read this post.
@engtech : The contents of the secure pages are hardly pushed into the RSS feeds anyway. So I don't think that's a big downside.
Does this assume a certain default server or browser setting?
If you install Fiddler, you'll be able to see the requests the browser is making. That should help find the problem.
The point of the "mixed secure and insecure content" warning is that the browser should not show the padlock icon - symbolic of "this content was encrypted" - on a page where some of the content on the page was not encrypted.
Browsers will not usually expose the certificate information of the certificates on 3rd party sites loaded into the page unless they are invalid.
The "trust" implied here only goes as deep as validation of identity - it's assumed that if every certificate is valid and signed by a root authority, then you can trust the content to be authentic.
The browser warnings happen when you mix the protocols, and this post shows a simple solution for avoiding the mixing.
Not everything is a web application. Some of us develop sites that we like Google to be able to index, so grabbing all of the context via ajax is not a viable solution.
That's a good point. You want to make sure the server supports https before using this technique.
I first saw this technique used in the markup of the html5 boilerplate to load jQuery in either http or https environments, this of course came years after this post was written.
And its working fine.
Add a comment: