views:

125

answers:

4

This one is driving me nuts. It's (yet) another IE6/7 idiosyncrasy, but one of my web pages needs to be loaded using https. In IE6/7 I get the dreaded "contains secure and nonsecure items" message which is causing users to panic. I've gone through the code top to bottom and isolated the problem (as IE sees it) to background images in my CSS. However, these use absolute paths...

background: url(/images/imagename.jpg);

Looks like this is tripping up IE and causing the nonsecure message on https. Anybody got any ideas how to get around this? Any help much appreciated.

A: 

Try with:

background: url(//images/imagename.jpg);

According to this answer that should work. Try using it for the stylsheet as well, eg:

<link rel="stylesheet" type="text/css" src="//style/style.css" />
Marius
Tried this, but images vanished from all browsers :-(
DK
No dice, sorry.
DK
If you want this syntax to work, you have to use it like this://hostname/images/file.jpg
EricLaw -MSFT-
+2  A: 

That shouldn't be causing you any troubles, as long as the CSS file itself is also coming from HTTPS. Absolute paths without an explicit protocol (i.e. /path/to/file instead of http://example.com/path/to/file) inherit the protocol of the file calling them, be it HTML or CSS.

Can we see your page? It's possible there's something else on the page you're overlooking.

ceejayoz
Sorry, I'm afraid I can't provide a link here. I've checked for any HTTP requests though, and it's only CSS images. I also tried the page with no stylesheets and IE was happy. My stylesheets are referenced like href="/_css/screen.css" too, so no http ref there either.
DK
Can you provide sanitised source code for the page? Again, this sort of path should not be the cause of this behaviour.
ceejayoz
How did you monitor the HTTP requests? I would use Fiddler, making it a cinch to filter out non-HTTPS requests.
roryf
Can't provide source either I'm afraid - sorry. Fairly high-traffic/prominent website.As for monitoring HTTP requests, I can't use Fiddler because I'm on Mac. I just viewed all http:// requests in the source code, plus "View Page Information" in the Firefox Web Developer toolbar.
DK
If you're testing for problems with IE, it seems like a safe bet that you have a Windows machine around that you can use Fiddler on. But you should read the IEInternals article below for more help on this type of problem.
EricLaw -MSFT-
+1  A: 

You are correct, relative url paths in background style will cause this message to appear in IE6/7.

The only method I have used successfully, is to either build the absolute path from available browser data, or to hard code the absolute path. Here is an example of how you can build the absolute path with JavaScript:

Using a top level style definition like this:

<style type="text/css">
    .fixBgImage {
     background: url(/images/imagename.jpg);
 }
</style>

You can use a JavaScript function that looks up that rule, and changes the backgroundImage style for that rule. (Keep in mind that this example assumes you've defined the rule on sheet[0])

        // this function needs to be run after the page has loaded
        // (body.onload, window.onload or something similar)
        function fixBackgroundImages() {
            // using sheet 0 defined first on this page
            var rule = getRule('.fixBgImage', document.styleSheets[0]);         
            if (rule != null) {
             var bgUrl = rule.style.backgroundImage.replace(/^url|[\(\)]/g, '');
             bgUrl = fixHttpsBgUrl(bgUrl);
             rule.style.backgroundImage = 'url("' + bgUrl + '")';
            }
        }

        function getRule(name, sheet){
            var rules = (sheet.rules) ? sheet.rules : sheet.cssRules;

            for (var i = 0; i < rules.length; i++) {
             if (rules[i] && rules[i].selectorText == name) {
              return rules[i];
             }
            }

            return null; 
        }

       // This function returns an absolute path if https is used
       function fixHttpsBgUrl(imgUrl){
          if (document.location.protocol.indexOf('https') >= 0){
            var basepath = document.URL.substring(0, document.URL.lastIndexOf('/') + 1);
            var pcol = document.location.protocol + '//';
            var host = document.location.hostname;
            var port = (document.location.port) ? ':' + document.location.port : '';

            if (imgUrl.indexOf('/') == 0){ // server root path
              imgUrl = pcol + host + port + imgUrl;
            }
            else{  // app root
              imgUrl = basepath + imgUrl;
            }
          }
        }
FlashXSFX
Sorry, bit confused on how to implement this. Do I need to create a var for each image?
DK
Sorry, the solution I gave isn't really an automatic drop in. I changed the above to a function to make it more modular. You could build a new style rule in JavaScript that uses this function to define the background style. I will give an example momentarily.
FlashXSFX
Much appreciated. Surprised it's not a more common issue for people.
DK
Edited my response to include an example on how to use the original function... enjoy!
FlashXSFX
A: 

IE should have absolutely no problem with relative-pathed images so long as they're relative to a secure root. The problem you're hitting quite likely is caused elsewhere.

http://blogs.msdn.com/ieinternals/archive/2009/06/22/HTTPS-Mixed-Content-in-IE8.aspx

EricLaw -MSFT-