Forum Moderators: open

Message Too Old, No Replies

IE not caching content-negotiated image

IE always re-fetches content-negotiated images from server. Why?

         

cirrus

12:32 pm on Apr 11, 2004 (gmt 0)

10+ Year Member



I have made a web-page where I omit the file extension when I link to an image ( <img src="pic" /> instead of <img src="pic.png" /> for example).
This still causes my webserver to return the correct image since I have the 'MultiViews' option enabled, so the server looks for pic.* and chooses the most appropriate one to send back to the client - but in my case there is only ever one image so clients always get the same file no matter what.

I am doing this
a) to simplify maintenance - if I want to switch a GIF to a PNG or something like that I don't need to update all my pages and...
b) because using a little CGI I want to make the site themable. All the images' names have a common prefix, so to change a theme I just change the prefix and it refers to totally seperate bunch on images. However, equivaltent images in different themes may use different file formats which is why I'm avoiding the extensions

Ok, on to my problem. I set all of this up and it worked beautifully in Mozilla, Safari, Opera, IE (Mac version) and even iCab. Internet Explorer (windows version), however, reloads all of the images from the server on every page, every time. I use JavaScript rollover images on the page and even those reload every time you run the mouse over them. It appears to refuse to cache any of the images (whereas all the other browsers *do* cache them as usual). This obviously slows page loading for visitors and wastes my server's bandwidth.

I looked at my servers HTTP response headers (using wget) for the content-negotiated image files and they do have a few extra lines so I suspect that's what's causing it.
The old style response (when I request the file with the extension) is as follows snipped:

1 HTTP/1.1 200 OK
2 Date: Sun, 11 Apr 2004 11:57:24 GMT
3 Server: Apache/1.3.26 (Unix) Debian GNU/Linux PHP/4.1.2
4 Last-Modified: Thu, 08 Apr 2004 18:12:27 GMT
5 ETag: "6f1a-b89-4075960b"
6 Accept-Ranges: bytes
7 Content-Length: 2953
8 Keep-Alive: timeout=15, max=50000
9 Connection: Keep-Alive
10 Content-Type: image/png

Without the extension snipped I get:

1 HTTP/1.1 200 OK
2 Date: Sun, 11 Apr 2004 11:58:47 GMT
3 Server: Apache/1.3.26 (Unix) Debian GNU/Linux PHP/4.1.2
4 Content-Location: rose_home.png
5 Vary: negotiate
6 TCN: choice
7 Last-Modified: Thu, 08 Apr 2004 18:12:27 GMT
8 ETag: "6f1a-b89-4075960b;407845ce"
9 Accept-Ranges: bytes
10 Content-Length: 2953
11 Keep-Alive: timeout=15, max=50000
12 Connection: Keep-Alive
13 Content-Type: image/png

Lines 4,5 & 6 are new and the ETag is slightly different. This must be what makes IE not cache the file.... but why?

I tried adding an 'Expires' date to the header but it made no difference.
Presumably this would affect any transparently content-negotiated content so I assumed others would have had the same problem but I could not find any mention of it on google, msdn or within apache's documentation.

Does anyone have an idea how I can fix this?

The site I'm working on is snipped (it's for my girlfriend so excuse the cheesyness :P) Currently most pages still refer to images by their full names and hence behave well in IE - the only page I changed so far is the links page snipped - visually it should have the same style as the rest but the images will always reload in IE.

Any help would be much appreciated!

Cheers!

-James

[edited by: DaveAtIFG at 4:17 pm (utc) on April 11, 2004]
[edit reason] No URLs please - See Terms of Service [/edit]

bumpaw

4:10 pm on Apr 12, 2004 (gmt 0)

10+ Year Member



James, We are operating in a parallel universe. I just posted the same problem, but not as detailed as you did. If I would have just dropped down and seen yours I could have saved some bandwidth. My post is where yours originally was in Technology.

I am seeing my banner reload every time refresh is hit. I pulled this quote:

4. It may limit a public cache's ability to use the same response
for multiple user's requests.

from here [w3.org...]

cirrus

5:34 pm on Apr 12, 2004 (gmt 0)

10+ Year Member



I came across that too - if you are using content negotiation to make a real choice between different files (such as the same page in different languages) public chaching would be an issue, since different people going through the cache may well want to receive different langauges.

In my case I only have one file though, so the response is always the same and I *do* want it cached. I don't know if IE's behaviour is a bug or a feature (although in either case it would be nice if there was some documentation of it out there!) but as I said every other browser I tried did not have this problem.

As far as I can tell the only difference from IE's point of view (or any other client's for that matter) is the different HTTP response, so if we can find a way to change it back to the usual one I think the problem would be solved.

I came across apache's Header directive which allows you to remove or add lines to the HTTP header. I tried using it to 'fix' the header but it had no effect. According to the docs: "The Header directives are processed just before the response is sent by its handler. These means that some headers that are added just before the response is sent cannot be unset or overridden. This includes headers such as "Date" and "Server"." ( [httpd.apache.org...] ). I guess that's why it didn't work - although it's possible I made a mistake - can anybody confirm?

I just feel that there *must* be some simple way to fix this. Are we really the only ones having this problem?

-James

bumpaw

6:18 pm on Apr 12, 2004 (gmt 0)

10+ Year Member



Until it's resolved I have removed the set up for content negotiation on the site I'm building now. Images that are site-wide don't have to reload as each page is visited. It makes a big difference, and like you it's only IE 6.

cirrus

7:22 pm on Apr 12, 2004 (gmt 0)

10+ Year Member



Is it only happening in IE6?!? (I wouldn't know since that's the only one I tried) if it is it may well be a bug. Perhaps we should tell microsoft...

Until then I might try the Apache developers - see if they have any bright ideas.

Gotta go now! The bar is calling! ;)

-James

cirrus

8:03 pm on Apr 13, 2004 (gmt 0)

10+ Year Member



Yay!
I found a solution! I'm posting it here incase it's useful to anyone else.

Basically, I used a bit of mod_rewrite voodoo magic! :P

I created an .htaccess file in the directory with my images and added the following lines:
-----
Options -MultiViews

RewriteEngine on

RewriteCond /path/to/files/%{REQUEST_URI}.png -f
RewriteRule ^([^.]+)$ $1.png [S=2]

RewriteCond /path/to/files/%{REQUEST_URI}.jpg -f
RewriteRule ^([^.]+)$ $1.jpg [S=1]

RewriteCond /path/to/files/%{REQUEST_URI}.gif -f
RewriteRule ^([^.]+)$ $1.gif
-----

First I disable MultiViews since I'm gonna emulate it with mod_rewrite and don't want it to interfere.
Then I enable mod_rewrite and make three rules (one for each kind of image) - each rule has a condition that appends an extension (png, jpg or gif) to the requested file and checks if such a file exists. If so the rule is executed which appends the extension to the requested URL so that apache returns the desired file.

It works like a charm! ^_^

Now requesting a file from that folder without the extension returns the correct file but with normal headers that don't make IE go bezerk:

HTTP/1.1 200 OK
Date: Tue, 13 Apr 2004 20:13:30 GMT
Server: Apache/1.3.26 (Unix) Debian GNU/Linux PHP/4.1.2
Last-Modified: Thu, 08 Apr 2004 18:12:27 GMT
ETag: "6f1a-b89-4075960b"
Accept-Ranges: bytes
Content-Length: 2953
Connection: close
Content-Type: image/png

Hope this is helpful to anyone with the same problem!
Enjoy!

-James