views:

5566

answers:

4

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>
+13  A: 

Easiest way is to sling an ever-changing querystring on 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 webserver sends to disallow caching.

Dan
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!
brad
+2  A: 

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.

Jonathan Lonowski
+2  A: 

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.)

[Edit: minor correction to the js, also amazement that someone decided this is "wrong" enough vote it down]

[Edit by Mark Harrison: This is exactly the correct answer, thanks! Whoever marked it down is uninformed.]

[Edit (by olliej): I know, I actually implemented a number of these things so it confused me somewhat -- but then I was also briefly asked to verify i was not a robot (perhaps due to the two bug report URLs?) so figured that that may have been responsible]

olliej
A: 

Works brilliantly to refresh a captcha image generated by a PHP file as well - so simple!

Dr Paul