JavaScript: how to force Image() not to use the browser cache?

31,128

Solution 1

That actually sounds like a bug in the browser -- you could file at http://bugs.webkit.org if it's in Safari or https://bugzilla.mozilla.org/ for Firefox. Why do i say potential browser bug? Because the browser realises it should not be caching on reload, yet it does give you a cached copy of the image when you request it programmatically.

That said are you sure you're actually drawing anything? the Canvas.drawImage API will not wait for an image to load, and is spec'd to not draw if the image has not completely loaded when you try to use it.

A better practice is something like:

    var myimg = new Image();
    myimg.onload = function() {
        var rx=Math.floor(Math.random()*100)*10
        var ry=Math.floor(Math.random()*100)*10
        ctx.drawImage(myimg,rx,ry);
        window.setTimeout(draw,0);
    }
    myimg.src = 'http://ohm:8080/cgi-bin/nextimg'

(You can also just pass draw as an argument to setTimeout rather than using a string, which will save reparsing and compiling the same string over and over again.)

Solution 2

The easiest way is to sling an ever-changing querystring onto the end:

var url = 'http://.../?' + escape(new Date())

Some people prefer using Math.random() for that instead of escape(new Date()). But the correct way is probably to alter the headers the web server sends to disallow caching.

Solution 3

You can't stop it from caching the image altogether within Javascript. But, you can toy with the src/address of the image to force it to cache anew:

[Image].src = 'image.png?' + (new Date()).getTime();

You can probably take any of the Ajax cache solutions and apply it here.

Share:
31,128
Mark Harrison
Author by

Mark Harrison

I'm a Software Engineer at Google where I work on machine learning planning systems. From 2001-2015 I was the Pixar Tech Lead of the Data Management Group. My 50-year charter was to store and catalog all data and metadata related to the Studio's feature films. This system ("Templar") is in use to this day. From 1997 to 2001 I lived in Beijing, China and was the Chief Software Architect at AsiaInfo, the company that built China's Internet. While there my software was used to grow the China Internet from 200K to 65M users. The last I heard they were at 350M+ users. I studied computer science and worked in Texas for many years. I wrote a couple of computer books... the best one was in print for 20 years. Feel free to drop me a line! [email protected]

Updated on March 16, 2020

Comments

  • Mark Harrison
    Mark Harrison about 4 years

    If I load the nextimg URL manually in the browser, it gives a new picture every time I reload. But this bit of code shows the same image every iteration of draw().

    How can I force myimg not to be cached?

    <html>
      <head>
        <script type="text/javascript">
          function draw(){
            var canvas = document.getElementById('canv');
            var ctx = canvas.getContext('2d');
            var rx;
            var ry;
            var i;
    
            myimg = new Image();
            myimg.src = 'http://ohm:8080/cgi-bin/nextimg'
    
            rx=Math.floor(Math.random()*100)*10
            ry=Math.floor(Math.random()*100)*10
            ctx.drawImage(myimg,rx,ry);
            window.setTimeout('draw()',0);
          }
        </script>
      </head>
      <body onload="draw();">
        <canvas id="canv" width="1024" height="1024"></canvas>
      </body>
    </html>
    
  • brmore
    brmore over 14 years
    Dan, kind of old post but I surely owe you a beer on this one. Not exactly my situation, but gave me great idea. Thanks!
  • Guillaume Gendre
    Guillaume Gendre over 11 years
    I had to use it without the ending slash : var url = 'http;//.../something.png'+'?'+Math.random(), but it's working fine ! +1 for the headers advisory :)
  • evilSnobu
    evilSnobu over 6 years
    Does Cache-Control: no-cache help here? While I appreciate the nifty workaround I can't help but wonder if this is the best we can do right now.. what kind of hacks did we use in the moon lander code then?
  • Ng Sek Long
    Ng Sek Long over 3 years
    escape is deprecated, please use encodeURI instead. See w3schools.com/jsref/jsref_escape.asp