Search code examples
javascriptcsstornado

Why would an image fail to load from CSS when the path is correct, but loads when URL entered directly?


I have a situation where css background-images are failing to load in my webapp. That is odd about this is that they are using absolute paths (beginning with "/") and that the paths are correct.

When I expect the element with DOM Inspector, firefox gives the error "Could not load the image." Yet, if I click on that link, the image opens in a new tab, showing that the path is correct.

Demonstration: https://qa.hubble.in/#subscriptions

On the upper-right of this page, there are five squares. This is the main app navigation menu and should have icons. If you right click and choose "Inspect element" on the left most square, the inspector opens on the "a title=Dashboard" element. If you go to it's parent, "li class=nav_dashboard" you can see what I'm talking about.

The CSS in the inspector shows this:

ul.nav-tabs li.nav_dashboard, li.nav_dashboard.active {
    background-image: url('/images/icons/liveViewInactive.svg');
}

Yet, vexingly, if you open https://qa.hubble.in/images/icons/liveViewInactive.svg in your browser, you can see the icon. Why is it not loading when specified from CSS? Is there some obscure rule that I am unaware of?

More info:

The web server is tornado http server and I haven't had any issues like this before. I really can't see any reason why the images wouldn't get served when request by CSS, just the way they always have.

The same code runs fine in my development environment: https://darrel.hubble.in/#subscriptions, but I'm afraid to push anything to production until I resolve this issue in the qa environment. The only difference between the two is that darrel.hubble.in, the one which works, is running in an elasticbeanstalk instance instance, and qa.hubble.in, the one which has this mysterious problem, is running in a regular amazon ec2 instance. Hard to imagine how that could cause this.

Edit (solution):

This appears to be a bug in the way the tornado StaticFileHandler serves the content-type for svg files.

To fix it, I subclassed tornado.web.statcifilehandler (I was subclassing it anyway for other reasons), and added this:

if ".svg" in self.absolute_path:
    self.set_header("Content-Type", "image/svg+xml")

Solution

  • Checking the console when loading the webpage you cite, there are the following errors for all the SVGs:

    Resource interpreted as Image but transferred with MIME type text/html
    

    You need to set up your server to transfer these images as SVGs, with type image/svg+xml. On Apache servers, it's as simple as adding this to an .htaccess file or to your server config:

    AddType image/svg+xml svg
    

    Clear the cache on your browser(s) and reload the page.

    Planet SVG has full instructions on setting up Apache and other servers for SVGs