Open Bug 295942 Opened 18 years ago Updated 8 months ago

Mozilla will ignore javascript-triggered image reload even if image is expired


(Core :: Graphics: ImageLib, defect)

Windows XP





(Reporter: juergen, Unassigned)


User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.7.8) Gecko/20050511 Firefox/1.0.4
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.7.8) Gecko/20050511 Firefox/1.0.4

We have a static html page which contains an image. The image is reloaded using
javascript every second. Mozilla completely ignores this and does never reload
the image.
This is actually a known problem and most people work arround this by appending
random or time-based strings to the url to force Mozilla to reload the image 

Our case is slightly different. The image is server-generated and the server
also sends the following header fields:

Last-Modified = [current time]
Cache-Control = no-store
Cache-Control = max-age=[n seconds], must-revalidate
Expires = [current time + n seconds]

The max-age can be anywhere between 1 and 5 seconds. The image reload is
triggered every second.

Reproducible: Always

Steps to Reproduce:
1. Set up a html page with an image and a Javascript that periodically reloads
the image
2. Set up a server that generates the image and sends correct expiry information
3. Watch Mozilla NOT reload the image

Actual Results:  
Mozilla does never reload the image. Not if the image is still valid and not
after the image has expired. Since we could accept this behaviour for the
image.src=something script we did a direct DOM manipulation:

var image = new Image();
var oldImage = document.getElementById('generatedimage');
oldImage.parentNode.replaceChild(image, oldImage);
image.setAttribute("id", "generatedimage");

The script is executed without errors or warnings every second but still the
image is NEVER reloaded.

Expected Results:  
Mozilla should reload the image after it has expired.
IE actually does this. If the image has not yet expired IE does not reload the
image but after it has expired it is reloaded.
Summary: Mozilla ignores javascript-triggered image reload even if image is expired → Mozilla will ignore javascript-triggered image reload even if image is expired
Sounds like the cache validation code in imglib is not working right....
-> default owner
Assignee: darin → nobody
There seem to be a number of bugs like this (183470, 432807, 470032, 326689, 338542 are possible duplicates).  I have an easily reproducible (and understandable) test case at  This is still an issue on recent nightly builds.

The test case keeps creating, adding and removing img elements with the same src but the image is never reloaded even though it is stale.

I've turned some of the logging on (imgRequest,cache,nsHttp).

This is the image being loaded the first time:
-1410337024[7fdcbee61480]: http response [
-1410337024[7fdcbee61480]:   HTTP/1.1 200 OK
-1410337024[7fdcbee61480]:   Server: nginx/1.0.10
-1410337024[7fdcbee61480]:   Date: Sat, 10 Mar 2012 00:36:41 GMT
-1410337024[7fdcbee61480]:   Content-Type: image/png
-1410337024[7fdcbee61480]:   Content-Length: 811
-1410337024[7fdcbee61480]:   Last-Modified: Fri, 07 Jan 2011 08:47:48 GMT
-1410337024[7fdcbee61480]:   Connection: keep-alive
-1410337024[7fdcbee61480]:   Keep-Alive: timeout=20
-1410337024[7fdcbee61480]:   Expires: Thu, 01 Jan 1970 00:00:01 GMT
-1410337024[7fdcbee61480]:   Cache-Control: no-cache
-1410337024[7fdcbee61480]:   Accept-Ranges: bytes
-1410337024[7fdcbee61480]: ]

A little later (still the same request) we get:
-1072605408[7fdcbee61040]: Must validate since response contains 'no-cache' header

But then when we the img tag comes along we get this:
-1072605408[7fdcbee61040]: -100035699 [this=7fdca93bfec0] imgLoader::LoadImage (aURI="") {ENTER}
-1072605408[7fdcbee61040]: -100035699 [this=7fdca93bfec0] imgLoader::ValidateEntry {ENTER}
-1072605408[7fdcbee61040]: -100035699 [this=7fdca93bfec0] imgLoader::ValidateEntry {EXIT}
-1072605408[7fdcbee61040]: -100035699 [this=7fdca93bfec0] imgLoader::LoadImage() adding proxyless entry (uri="")
-1072605408[7fdcbee61040]: -100035699 [this=7fdca7fb83a0] imgCacheEntry::Touch {ENTER}
-1072605408[7fdcbee61040]: -100035699 [this=7fdca0835a00] imgRequest::GetURI
-1072605408[7fdcbee61040]: -100035699 [this=7fdca7fb83a0] imgCacheEntry::Touch {EXIT}
-1072605408[7fdcbee61040]: -100035699 [this=7fdca93bfec0] imgLoader::LoadImage |cache hit| (request="7fdca0835a00")

I think it's gone wrong here - it looks like we've found the image in an image cache that doesn't know about the expiry rules.  I'm not sure when the entry in the image cache would expire or if the cache is shared between different pages but this doesn't really seem like the correct behaviour to me.

It's worth noting that some other browsers have similar issues but there isn't much consistency.  Perhaps it's worth raising this on a list somewhere (whatwg?) - it's difficult to deal with this issue without understanding what the browsers are doing but that doesn't appear to be documented anywhere.
The behavior you see there is in fact due to a non-HTTP-semantic per-document cache for images.  It's also explicitly allowed (in some cases required) by the HTML5 spec, as far as I can recall, at least in part because websites depend on it for "image preloading" behavior.
I can believe that some websites depend on this kind of behaviour, but I can't find anything in HTML5 about this (I had already looked there) and it isn't clear exactly what the behaviour is.  Either I'm not looking in the right place in HTML5 (can you have a look please?) or we should probably raise this on the whatwg list.
I just looked again, and the image loading section got heavily rewritten so I can no longer find anything about it.

The behavior, iirc, is simple: images are cached on a per-document basis, and unless evicted that cache is just a straight key on the url with no HTTP semantics behind it.

Raising this on the list may make sense, sure.
Component: Networking: Cache → ImageLib
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.