views:

1294

answers:

7

We have found out that Firefox (at least v3) and Safari don't properly cache images referenced from a css file. The images are cached, but they are never refreshed, even if you change them on the server. Once Firefox has the image in the cache, it will never check if it has changed.

Our css file looks like this:

div#news {
  background: #FFFFFF url(images/newsitem_background.jpg) no-repeat;
  ...
}

The problem is that if we now change the newsitem_background.jpg image, all Firefox users will still get the old image, unless they explicitly refresh the page. IE on the other hand, detects that the image has changed and reloads it automatically.

Is this a known problem? Any workarounds? Thanks!

EDIT: The solution is not to press F5. I can do this. But our clients will just visit our web site, and get the old, outdated graphics. How would they know they would need to press F5?

I have installed Firebug and confirmed what I already suspected: Firefox just doesn't even try to retrieve images referenced from a css file, to find out if they have been changed. When you press F5, it does check all images, and the web server nicely responds with 304, except for those that have changed, where it responds with 200 OK.

So, is there a way to urge Firefox to automatically update an image that is referenced from a css file? Surely I'm not the only one with this problem?

EDIT2: I tested this with localhost, and the image response doesn't contain any caching information, it's:

Server  Microsoft-IIS/5.1
X-Powered-By    ASP.NET
Date    Tue, 14 Oct 2008 11:01:27 GMT
Content-Type    image/jpeg
Accept-Ranges   bytes
Last-Modified   Tue, 14 Oct 2008 11:00:43 GMT
Etag    "7ab3aa1aec2dc91:9f4"
Content-Length  61196

EDIT3: I've done some more reading and it looks like it just can't be fixed, since Firefox, or most browser, will just assume an image doesn't change very often (expires header and all).

A: 

Try holding the SHIFT key while you click reload (or press F5).

Otherwise, use a tool such as Firebug to check the HTTP request/response headers and observe the header values that control caching. I've never noticed this problem. Perhaps your server is returning a 304 response (not modified).

Drew Noakes
This is not the solution, see edited question
Frederik Slijkerman
A: 

I know this probably isn't what you want to hear, but it's considerably more likely that Firefox is following the standard and IE is doing something slightly odd (and you just happen to rely on it ;)).

The caching behaviour depends on what caching headers are being sent with your images. If you're in a position to post the headers (or a URL to one of the images), then we'll be able to tell you more specifically what's going on.

Dan
+1  A: 

Verify your HTTP headers on the images you are serving up, as well as the CSS file(s).

If any of them are set to cache (or are missing), you will find the browser is correctly caching the file(s).

scunliffe
+1  A: 

To avoid such issue, I have seen webmasters adding version number to their files. So they load site-look-124.css and newsitem_background-7.jpg.

Not a bad solution, IMHO.

PhiLho
A: 

This won't fix the problem of Firefox not checking if the image has expired, but what you can do to ensure that your clients see the correct image is:

Set the image in the css to a PHP or similiar script that returns the image:

div#news {
  background: #FFFFFF url(images/background.php?name=newsitem) no-repeat;
  ...
}

Then use the script to return the image"

<?php
$name = isset($_REQUEST['name']) ? $_REQUEST['name'] : false;
switch($name) {
    case 'newsitem':
        $filename = 'news_item_background.jpg';
    break;
    default:
        $filename = 'common_background.jpg';
    break;
}

header("Content-Type: image/jpeg");
header("Content-Transfer-Encoding: binary");
$fp = fopen($filename , "r");
if ($fp) fpassthru($fp);

I use it on my home server to randomly return a background image for some of my pages, and Firefox doesn't seem to cache these. You can also do some funky stuph with the images if you like.

Jrgns
+5  A: 

I would just add a querystring value to the image url. I usually just create a "version number" and increment it every time the image changes:

div#news {
  background: url(images/newsitem_background.jpg?v=00001) no-repeat;
  ...
}
81bronco
We've come to the same conclusion here. We need to add some string to the image URL.
mark
use ctrl+f5 for reload
drorhan
A: 

One other quick work-around (if this mainly occurs in the middle of web designing) is to view the actual css page in firefox, and reload the page, then when you return to the website the browser will read the current css page.

of course this is a temp fix just for the web designer

in that case ctrl+f5 succifes for me, usually
Litso
*suffices of course
Litso