1

Here is the basic implementation of how i'm drawing an image to the canvas.

  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var imageObj = new Image();

  function drawImg(x, y) {
     imageObj.onload = function() {
       context.drawImage(imageObj, x, y);
     };
     imageObj.src = 'http://www.mysite.com/temp.jpg';
  }

I have a server side image rendering script, where I am writing an image to the same file location eg: "temp.jpg". I'm using Ajax to cue the browser when the image changes, and I run the function to load the image again. However, it seems since the URL is always the same, the first image loaded is cached and will never redraw.

I've found several solutions but I'm not sure what will work best or is the real optimal solution. Some suggestions have included slightly manipulating the URL with a timestamp, and I've seen some references to streaming.

Some key points:

  • I don't want to clear the canvas, I want the most recent image to be on top of the previous image, in the event the x,y coordinate change or the image size is different, it's supposed to layer.
  • I really don't want to change the image filename for each new image, that seems overkill.

Thank you.

Edit:

Decided to include my github project for the socket.io version of this I am working on. I've got about 5 different versions in the works but this is the one I'm tracking mostly. Feel free to rip it apart I'm sure I have some bad practices when it comes to memory management. https://github.com/Pwn9/tcp-io-bridge

tremor
  • 2,518
  • 16
  • 34

3 Answers3

2

IMO, the best solution is to add a timestamp (you might add a random value also, just to be sure) to the image as a parameter. This avoids having to store a specific variable counter and is really easy to implement. Perhaps something like:

"?" + +new Date() + "_" + Math.random ()

You might also simply want to avoid caching altogether, but this is problematic if you are NOT converting all of your images to canvas objects, since in most Webkit-based browsers, in-between-refreshes image caching is disabled if between-pages caching is also disabled..

[edit:] Or, in other words, in Webkit-based browsers, if you reload something with Javascript and your header says "expired", the image will be re-requested. In IE11 and Firefox, the image will be cached until the page refresh, even if caching is disabled.

http://code.google.com/p/chromium/issues/detail?id=336292

Agamemnus
  • 1,279
  • 2
  • 16
  • 38
  • A combination of this and setting my server headers to no-cache is working out to be the best solution so far. – tremor Feb 04 '14 at 21:37
1

Maybe you can do something roughly like this:

  var i = 0;

  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var imageObj = new Image();

  function drawImg(x, y) {
     imageObj.onload = function() {
       context.drawImage(imageObj, x, y);
     };
     imageObj.src = 'http://www.mysite.com/temp.jpg?' + i;
     i++;
  }

This way you'll get a list of urls like:

This seems to make Chrome send a web request, where as if you kept the url the same, no web request is sent at all.

I tested in Chrome and this does force a new image to be loaded. I would also set your headers to not cache that url.

I'm testing a few other browsers right now.

Gohn67
  • 10,390
  • 2
  • 26
  • 34
  • Wouldn't this create a cached image for each request though? Or can I handle that by not allowing caching via html headers? This has been the solution I am leaning toward so far. – tremor Feb 04 '14 at 20:41
  • Yeah that's why you set no cache headers in your http response – Gohn67 Feb 04 '14 at 20:42
1

Having had cache issues with complex form pages that behave like small single page applications, my usual solution is to set various no cache headers on the response. This means that you need to be able to configure that on your web server or do it in server side code.

These are the typical cross-browser headers:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

See this answer for server side code samples: https://stackoverflow.com/a/2068407/2836187

Community
  • 1
  • 1
azurelogic
  • 781
  • 5
  • 11