/ English / tech /

IE DHTML image caching bug: workaround

Internet Explorer is known for great many strange and obscure bugs, and this is just one of them.  It affects versions 5.5SP2 and 6.0 of IE for Windows.  Here is a brief explanation and a solution offered. I found the bug while implementing a feature for EPrints software.

Original research was done in October, 2005.  This version was written: 2005-11-30 15:14.

Update from 2007-05-17: A guy named Jay Link reports a JavaScript solution.

In some configurations Internet Explorer for Windows of the affected versions will try to reload every image file for every image element that you add to a webpage via JavaScript, be it DOM methods or the proprietary innerHTML method.  It will also reload background image (e.g. CSS-specified) for every element you create, if there is any.

This means: for each image that you add to the document, it will send a request to the server, even if there are several copies of the same image in the document.  It will not cache it.  I have seen it sending HEAD requests with If-Modified-Since header (see HTTP protocol), to which Apache responded with 304 Not Modified responses. Others claim seeing it reloading every image file in full, as if there were no cache at all.

The bug is especially likely to hit your AJAX applications.

Test this bug

As far as my tests have shown, this happens when the IE cache settings is set to “Every visit to the page”. (To open IE’s cache settings dialog: Internet Options / General tab / Temporary Internet files box / Settings… button.) If it is set to "Every time you start Internet Explorer" or to “Automatic” or to “Never”, this does not happen.

Microsoft has a note on its website with a description of this bug and offers a workaround.  It is fun (in a sad way) to note that it states: “This behavoir is by design.” It is even more fun (in an even sadder way) to find, that the offered workaround does not help at all.

As far as I understand, the default setting in Internet Explorer is “Automatic”, so even if you were hit by this bug, probably most users won’t.

But if you want to be sure and to make it work smooth even for those few that have this setting in an unfortunate state, there is a workaround.

The workaround

To fix this problem you can make your server add an “Expires” HTTP header to your image files.  Then if this header points to a date in the future, IE will cache them, no matter what cache setting is in effect and will not try to revalidate the cached copy every time.

I use Apache for the server and, to generate the “Expires” header, I use the mod_expires module.  So, first of all, I ensured that this module is available to Apache.

In my case I had to recompile Apache, but for you adding these lines into httpd.conf may be enough:

LoadModule expires_module libexec/mod_expires.so
AddModule mod_expires.c

Second, to the virtual host configuration I added this:

<location /images/>
  <IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
 </IfModule>
</location>

And restarted Apache.  That’s it.

I checked the headers by running:

ivan@zetta:~/tmp> wget -S http://isaiah.zet/images/profileinfo.png
--12:00:27--  http://isaiah.zet/images/profileinfo.png
           => `profileinfo.png.6'
Resolving isaiah.zet... done.
Connecting to isaiah.zet[192.168.0.3]:80... connected.
HTTP request sent, awaiting response...
 1 HTTP/1.1 200 OK
 2 Date: Thu, 20 Oct 2005 09:00:27 GMT
 3 Server: Apache/1.3.33 (Unix) mod_perl/1.29
 4 Cache-Control: max-age=2592000
 5 Expires: Sat, 19 Nov 2005 09:00:27 GMT
 6 Last-Modified: Fri, 14 Oct 2005 13:00:51 GMT
 7 ETag: "22f3e6-f6-434fac03"
 8 Accept-Ranges: bytes
 9 Content-Length: 246
10 Content-Type: image/png
11 Connection: close

100%[=...=======================>] 246          240.23K/s    ETA 00:00

12:00:27 (240.23 KB/s) - `profileinfo.png.6' saved [246/246]

Other ways to fix it

See that page by Dan POPA.

Other people’s studies

Several people have already found and mentioned this problem: