none
Image size is incorrectly cached when the image is modified. RRS feed

  • Question

  • On a web page you can dynamically load an image in javascript and then display the size of the image. No problem. Then if you overwrite the image with one of a different size (but the same name) the new image will display but the old size is cached.  The really bizarre thing is that if you close your browser and clear your cache and then go back to the page it STILL gets the size wrong.

     

    Does anyone have a solution to this where the correct image size can be retrieved after the image has changed?  Why does IE cache this?

     

    Sample page:

     

    <html xmlns="http://www.w3.org/1999/xhtml">

    <head>

    <title>Test</title>

    </head>

    <body onload="LoadGif();">

    <div>

    <input type="button" id="btnTest" value="Get Size" onclick="return GetSize();" />

    </div>

    <script type="text/javascript">

    var obj = null;

    function LoadGif()

    {

    obj = document.createElement("img");

    obj.src = "test1.gif";

    document.body.appendChild(obj);

    }

    function GetSize()

    {

    alert("x: " + obj.width + " y: " + obj.height);

    return false;

    }

    </script>

    </body>

    </html>

     

    Tuesday, February 19, 2008 11:27 PM

Answers

  • Hi John,

     

    Thanks for the details steps to reproduce; they were very clear and very helpful.  After a great deal of experimentation, I think I may have a workaround for you.

     

    Code Snippet

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Test</title>
    </head>

    <body onload="LoadGif();">
    <div>
    <input type="button" id="btnTest" value="Get Size" onclick="return GetSize();" />
    </div>


    <script type="text/javascript">
    var obj = null;
    function LoadGif()
    {
      obj = document.createElement("<img src='test1.gif'>");
    //  obj.src = "test1.gif";
      document.body.appendChild(obj);

    }

    function GetSize()
    {
      alert("x: " + obj.width + " y: " + obj.height);
      return false;
    }

    </script>
    </body>
    </html>

     

     

    Notice the highlighted lines?  For some reason that is not yet clear to me, setting src in the call to createElement() forces the image to size properly.  From what I can tell, the resizing problem appears when you set src after the call.  There may be more to it than what we're seeing here, but at least this should help you get up and running.

     

    Hope this helps...

     

    -- Lance

    Wednesday, February 27, 2008 12:21 AM
    Moderator

All replies

  • Hi John,

     

    I ran your sample (please remember to check the code sample checkbox in the future) and wasn't able to reproduce the problem you reported.  I notice that the sample you provided doesn't appear to load a different image.  Can you clarify the steps to reproduce your problem.  Alternatively, you could rework the sample.

     

    Thanks in advance...

     

    -- Lance

     

    Tuesday, February 26, 2008 10:36 PM
    Moderator
  • Hi Lance.  Sorry I forgot to check the box.  I appreciate you getting back to me on this.

     

    Repro steps:

     

    1. Create a html file that contains the sample html code from my first post and copy it to an available IIS virtual directory.

    2. Create a GIF image file in the same directory as the html file and name it "test1.gif" to match the name used in the html code.

    3. Navigate to the web page using IE 7 and verify that the image loads.

    4. Click the "Get Size" button and make a note of the width and height returned.

    5. Close the browser.

    6. Open the "test1.gif" image file and change the size.  You may also want to modify the image visually.  Or you can completely replace it with a different image (as long as the size is different) but the name of the image must remain "test1.gif".

    7. Open IE 7 and clear the cache.

    8. Navigate to the web page and verify that the new image loads and looks correct..

    9. Click the "Get Size" button and make a note of the width and height returned.

     

    The problem is that although the image does indeed change and the page does show the correct image, the size of the original image is returned instead of the size of the new image.  I have a product in the marketplace that is choking on this because a client is using images with the same name but different sizes and IE won't grab the new size.  Is there a way to clear the image size cache?

     

    Thanks.

     

    Tuesday, February 26, 2008 10:51 PM
  • Hi John,

     

    Thanks for the details steps to reproduce; they were very clear and very helpful.  After a great deal of experimentation, I think I may have a workaround for you.

     

    Code Snippet

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Test</title>
    </head>

    <body onload="LoadGif();">
    <div>
    <input type="button" id="btnTest" value="Get Size" onclick="return GetSize();" />
    </div>


    <script type="text/javascript">
    var obj = null;
    function LoadGif()
    {
      obj = document.createElement("<img src='test1.gif'>");
    //  obj.src = "test1.gif";
      document.body.appendChild(obj);

    }

    function GetSize()
    {
      alert("x: " + obj.width + " y: " + obj.height);
      return false;
    }

    </script>
    </body>
    </html>

     

     

    Notice the highlighted lines?  For some reason that is not yet clear to me, setting src in the call to createElement() forces the image to size properly.  From what I can tell, the resizing problem appears when you set src after the call.  There may be more to it than what we're seeing here, but at least this should help you get up and running.

     

    Hope this helps...

     

    -- Lance

    Wednesday, February 27, 2008 12:21 AM
    Moderator
  • Thanks Lance.  I believe that will work for me.  What a strange bug though eh?  Perhaps a fix will find it's way into a future release of IE?

     

    Thanks again.

     

    Wednesday, February 27, 2008 1:03 AM
  • This is still an issue in IE8. I spent 8 hours today trying to find a work around for this problem, but did not find a way to clear the cached image dimensions. Even resterting IE8 does not clear this bizarre internal image cache.

    Unfortunantly the suggested solution above:

    obj = document.createElement("<img src='test1.gif'>");

    won't work for me because I need to attach 'onload' & 'onerror' events before loading the image.

    The only solution is to rename the file when changing an image's dimensions.


    Friday, May 27, 2011 9:28 PM
  • I've got a couple of workarounds, two variants on a theme.

    The first is simple: add a unique query string to the image's src so that it's treated like a new image and loaded afresh (including its dimensions):

    var img = new Image(), src = 'images/test.gif';
    img.src = src + '?' + new Date().getTime();
    document.body.appendChild(img)

    The disadvantage of this is that either you have to use a unique query string as above every time the page loads, thereby essentially preventing the image from being cached, or you have to hardwire a query string into your code and change that every time the image is changed.

    If you really want the image to be inserted in the document with a query-string-less filename, a slightly obscure alternative is to use the query-string version of the image to get its proper dimensions, then explicitly state those dimensions when creating an image using the query-string-less filename:

    var src = 'images/test.gif';
    var img = new Image();
    img.onload = function () {
    	img.onload = null;
    	var w = img.width, h = img.height;
    	img = new Image(w, h);
    	img.src = src;
    	document.body.appendChild(img);
    }
    img.src = src + '?' + new Date().getTime();

    The disadvantages of this approach are (1) it has to load the image twice (at least when the image  first changes); and (2) the code has to wait for the query-string version of the image to load before it can load the query-string-less version, though here's a way around that latter problem:

    var src = 'images/test.gif';
    var img = new Image();
    img.src = src;
    document.body.appendChild(img);
    var img2 = new Image();
    img2.onload = function () {
    	img2.onload = null;
    	img.width = img2.width, img.height = img2.height;
    }
    img2.src = src + '?' + new Date().getTime();
    This inserts the query-string-less image and, once they're available via the query-string version of the image, sets the dimensions of the query-string-less image.
    Friday, May 17, 2013 9:49 AM