Re: [Zope] Browser Sticky Fingers
Hmmm, I'm staring at web sites that -do- update their graphic content, such as weather display sites and the MRTG (network graph stats) program, and I don't see anything like a variable URL. How do they manage it? The only new item I see is the use of: <META HTTP-EQUIV="Refresh" CONTENT=300> <META HTTP-EQUIV="Expires" CONTENT="...a date"> While this would cause the HTML to refreshed periodically, how are they getting the browser to re-fetch the *images*? I've captured the HTML source for several iterations and the <IMG SRC="blah"...> part never changes, so I would expect the same graphic would keep appearing on each cycle. -Jeff Rush On Tue, 19 Oct 1999 09:16:24 +1000, Anthony Baxter wrote:
Yep. Browsers suck. They cache images regardless. The disgusting hack is to always call your image with the current time in the URL - eg. <img src="/your/image/method?dummy_ts=<dtml-var "ZopeTime().timeTime()">"> /your/image/method should feel entirely free to ignore dummy_ts.
This way the image has a different URL, and so the browser doesn't use a cached one.
When you're producing on-the-fly live statistics as a graph, this hideous misfeature is a complete pain in the clacker.
At 16:49 19/10/99 , Jeff Rush wrote:
Hmmm, I'm staring at web sites that -do- update their graphic content, such as weather display sites and the MRTG (network graph stats) program, and I don't see anything like a variable URL.
How do they manage it? The only new item I see is the use of:
<META HTTP-EQUIV="Refresh" CONTENT=300> <META HTTP-EQUIV="Expires" CONTENT="...a date">
While this would cause the HTML to refreshed periodically, how are they getting the browser to re-fetch the *images*? I've captured the HTML source for several iterations and the <IMG SRC="blah"...> part never changes, so I would expect the same graphic would keep appearing on each cycle.
What kind of URL is pointing to the image? What headers are returned when retrieving the image? -- Martijn Pieters, Web Developer | Antraciet http://www.antraciet.nl | Tel: +31-35-7502100 Fax: +31-35-7502111 | mailto:mj@antraciet.nl http://www.antraciet.nl/~mj | PGP: http://wwwkeys.nl.pgp.net:11371/pks/lookup?op=get&search=0xA8A32149 ------------------------------------------
At 16:49 19/10/99 , Jeff Rush wrote:
Hmmm, I'm staring at web sites that -do- update their graphic content, such as weather display sites and the MRTG (network graph stats) program, and I don't see anything like a variable URL.
How do they manage it? The only new item I see is the use of:
<META HTTP-EQUIV="Refresh" CONTENT=300> <META HTTP-EQUIV="Expires" CONTENT="...a date">
While this would cause the HTML to refreshed periodically, how are they getting the browser to re-fetch the *images*? I've captured the HTML source for several iterations and the <IMG SRC="blah"...> part never changes, so I would expect the same graphic would keep appearing on each cycle.
possibly the src= of the <img> points to a cgi program that returns "Expires: (something soon)" headers so it wont get cached. in perl pseudocode (sorry i'm not that accustomed to python yet) you'd write something like this: # this from thimble smith, tim@desert.net # read image data $img = <wherever you get the image data from, gif assumed> # print expires with date=now print "Expires: ", scalar(localtime), "\r\n"; # or whatever content, then insert gif data print "Content-type: image/gif\r\n\n$img" hth? peter. -- _________________________________________________ peter sabaini, mailto: sabaini@niil.at -------------------------------------------------
At 5:45 pm +0200 19/10/99, Peter Sabaini wrote:
possibly the src= of the <img> points to a cgi program that returns "Expires: (something soon)" headers so it wont get cached.
in perl pseudocode (sorry i'm not that accustomed to python yet) you'd write something like this:
# this from thimble smith, tim@desert.net # read image data $img = <wherever you get the image data from, gif assumed> # print expires with date=now print "Expires: ", scalar(localtime), "\r\n"; # or whatever content, then insert gif data print "Content-type: image/gif\r\n\n$img"
Neat! It looks like the place to change this is in the index_html method of OFS/Image.py You *could* add an Expires header to the group of RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime)) RESPONSE.setHeader('Content-Type', self.content_type) lines near the end of this method, but I think that will mean that *all* images from a Zope system will be expired. A better solution would be if you could send an Expires header to the Image object. One thing I do is have an external method called 'img' at the root of my Zope structure and call images so <img src="img?src=tone.gif">. It consists of this; def img(self, src, RESPONSE): import os try: img_dir = self.images_dir except AttributeError, NameError: img_dir = '/home/nmedfac/guide_images' typemap={'.gif' : 'image/gif', '.jpg' : 'image/jpeg'} img_name=os.path.join(img_dir, src) img_ext = img_name[-4:] img_type = typemap[img_ext] # Open file, using 'rb' to open it in binary mode! img_file=open(img_name, 'rb') img_data=img_file.read() img_file.close() # Set the content-type of the response RESPONSE.setHeader('content-type', img_type) return img_data and there's nothing to stop you adding the Expires header before the Content-type header. Note that this means your images must live in a real live directory and *not* in the ZODB. Note also that I've got a property called 'images_dir' that is the directory where the images live. That way the same code works for however many subsites you've got. hth tone. ------ Dr Tony McDonald, FMCC, Networked Learning Environments Project http://nle.ncl.ac.uk/ The Medical School, Newcastle University Tel: +44 191 222 5888 Fingerprint: 3450 876D FA41 B926 D3DD F8C3 F2D0 C3B9 8B38 18A2
Tony McDonald wrote:
At 5:45 pm +0200 19/10/99, Peter Sabaini wrote:
possibly the src= of the <img> points to a cgi program that returns "Expires: (something soon)" headers so it wont get cached.
in perl pseudocode (sorry i'm not that accustomed to python yet) you'd write something like this:
# this from thimble smith, tim@desert.net # read image data $img = <wherever you get the image data from, gif assumed> # print expires with date=now print "Expires: ", scalar(localtime), "\r\n"; # or whatever content, then insert gif data print "Content-type: image/gif\r\n\n$img"
Neat! It looks like the place to change this is in the index_html method of OFS/Image.py
You *could* add an Expires header to the group of
RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime)) RESPONSE.setHeader('Content-Type', self.content_type)
lines near the end of this method, but I think that will mean that *all* images from a Zope system will be expired. A better solution would be if you could send an Expires header to the Image object.
What if the image object had an expires property that, when set, would include those headers, and when unset would be 'normal' non-expiring images? By default, the property would be unset, of course. This seems, IMHO, to be a zopish way of doing it. -- "They laughed at Columbus, they laughed at Fulton, they laughed at the Wright brothers. But they also laughed at Bozo the Clown." -- Carl Sagan
At 18:24 19/10/99 , Tony McDonald wrote:
At 5:45 pm +0200 19/10/99, Peter Sabaini wrote:
possibly the src= of the <img> points to a cgi program that returns "Expires: (something soon)" headers so it wont get cached.
in perl pseudocode (sorry i'm not that accustomed to python yet) you'd write something like this:
# this from thimble smith, tim@desert.net # read image data $img = <wherever you get the image data from, gif assumed> # print expires with date=now print "Expires: ", scalar(localtime), "\r\n"; # or whatever content, then insert gif data print "Content-type: image/gif\r\n\n$img"
Neat! It looks like the place to change this is in the index_html method of OFS/Image.py
You *could* add an Expires header to the group of
RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime)) RESPONSE.setHeader('Content-Type', self.content_type)
lines near the end of this method, but I think that will mean that *all* images from a Zope system will be expired. A better solution would be if you could send an Expires header to the Image object.
A better solution, immediatly applicable, is to use the 'precondition' property of the File and Image objects. On Image objects you can't edit this property via the management interface, but you can set it using an external method (imagename.precondition='precondition'). If the precondition attribute is set to a nonempty string, it is the name of a method to call. This could be anything callable. It is expected to raise an error if certain conditions aren't met, for example, when someone doesn't have the right cookie to download a certain File. But it could also be used to manipulate the RESPONSE object. So if you make a method ExpireNow that doesn't do anything but do RESPONSE.setHeader('Expires', ZopeTime().rfc822()), and use an external method to set the image's precondition to ExpireNow, this _should_ work. I have not tested this though. One caveat I can see with this method: If you click on the Change button on the Image Edit tab, the precondition attribute is set to ''. You could create a ZClass based on Image that only defines a new edit screen that includes the precondition property, this would solve the need for an external method as well. -- Martijn Pieters, Web Developer | Antraciet http://www.antraciet.nl | Tel: +31-35-7502100 Fax: +31-35-7502111 | mailto:mj@antraciet.nl http://www.antraciet.nl/~mj | PGP: http://wwwkeys.nl.pgp.net:11371/pks/lookup?op=get&search=0xA8A32149 ------------------------------------------
participants (5)
-
Bill Anderson -
Jeff Rush -
Martijn Pieters -
Peter Sabaini -
Tony McDonald