One solution to consider is the Content Security Policy upgrade-insecure-requests
directive.
The upgrade-insecure-requests
directive instructs user agents to
treat all of a site's unsecure URL's (those served over HTTP) as
though they have been replaced with secure URL's (those served over
HTTPS). This directive is intended for web sites with large numbers of
unsecure legacy URL's that need to be rewritten.
It’d amount to configuring your Web server so all pages on your site get served with this header:
Content-Security-Policy: upgrade-insecure-requests
So the effect of adding that header would be: for any page at your site served with an https
URL, any time a browser sees in one of those pages an http
URL for an embedded (sub)resource —whether it be a URL for a stylesheet, script, image, video, or whatever—the browser will automatically (transparently) try to fetch the resource from the corresponding https
URL instead.
For more details, you can see the Upgrade Insecure Requests spec.
2018-05-11 update
The upgrade-insecure-requests
directive is now supported in all major browser engines (including Edge 17+ and Safari 10.3+):
https://caniuse.com/#feat=upgradeinsecurerequests
The downside of using it now is, so far it’s only supported in Firefox (since Firefox 42) and Chrome. But it also:
P.S., I work at the W3C, where we recently (finally) enabled TLS/https access to all W3C site resources—and since the W3C has hundreds of thousands (maybe millions) of pages with http
URLs for embedded subresources, the way we were able to make it happen was in part by serving the Content-Security-Policy: upgrade-insecure-requests
header across the entire site.
The article Supporting HTTPS and HSTS on w3.org gives more info about the deployment details.