Include a page you'll write to define Greenwich Mean Time (GMT) as an HTTP date/time stamp. Use the ColdFusion createUUID function to provide a universally unique ID string.
Provide code to produce a header for each keyword found in the Mode in the query string. If requested, produce headers containing dates and an entity tag to help browsers and caches decide (if they bother to look) that the content might have changed: a last-modified date, an entity tag, an expiration date, or some combination of these. (By default, the Web server gives the date the page was served; so, you won't have to supply it.)
<cfinclude template="gmt.cfm"> <cfset Unique=createUUID()> <cfparam name="Mode" default=""> <cfif Mode contains "NewLast"> <cfheader name="last-modified" value="#GMT#"> <cfelseif Mode contains "OldLast"> <cfheader name="last-modified" value="Wed, 08 Jan 2003 05:15:30 GMT"> <cfelseif Mode contains "BadLast"> <cfheader name="last-modified" value="-1"> </cfif> <cfif Mode contains "NewEtag"> <cfheader name="etag" value="#Unique#"> <cfelseif Mode contains "OldEtag"> <cfheader name="etag" value="bogus"> </cfif> <cfif Mode contains "NewExpires"> <cfheader name="expires" value="#GMT#"> <cfelseif Mode contains "OldExpires"> <cfheader name="expires" value="Mon, 06 Jan 2003 04:15:30 GMT"> <cfelseif Mode contains "BadExpires"> <cfheader name="expires" value="-1"> </cfif>
Then if requested, add directives to tell the caches and browser how to handle this information: pragma, must-revalidate, no-cache, no-store, private, max-age, or some combination of these.
<cfif Mode contains "Pragma"> <cfheader name="pragma" value="no-cache"> </cfif> <cfif Mode contains "Must"> <cfheader name="cache-control" value="must-revalidate"> </cfif> <cfif Mode contains "Nocache"> <cfheader name="cache-control" value="no-cache"> </cfif> <cfif Mode contains "Nostore"> <cfheader name="cache-control" value="no-store"> </cfif> <cfif Mode contains "Private"> <cfheader name="cache-control" value="private"> </cfif> <cfif Mode contains "Maxage"> <cfheader name="cache-control" value="private"> </cfif>
If requested, add a form button to post the file (to see the impact of posting on instant replay).
<cfif Mode contains "Post"> <form method="post"> <input type="submit"> </form> </cfif>
Finally, display the time and the entity tag. If the user sees the same data twice, instant replay has occurred. Provide instructions for clarity.
<cfoutput>#GMT#<br> #Unique#</cfoutput> <p> Note the time and/or Etag above.<br> Refresh. Did the time change? Use the back button to return.
<cfscript>
function gmt(){
// Gets GMT date/time (GMT) from local time
TZ=getTimeZoneInfo();
DT=now();
GDT=dateAdd('s',TZ.utcTotalOffset,DT);
GMTDt=DateFormat(GDT,'ddd, dd mmm yyyy');
GMTTm=TimeFormat(GDT,'HH:mm:ss');
GMT="#GMTDt# #GMTTm# GMT";
return GMT;
}
</cfscript>
<cfset GMT=gmt()>
Provide instructions for six months from now so you 'll know how to use the page. Then to display submitted radio button values, create "Show" variables that are either empty (so the box won't be checked) or the string "checked" to make them checked. Because you need to do this for every possible value of each form variable that's fed by a radio button, the code is more lengthy than you might expect.
Specify headers you want the linked page to use.<br> The linked page will generate the headers named in the URL you use to reach it.<br> <cfset MyMode=""> <cfparam name="form.Etag" default=""> <cfset ShowNoEtag=""> <cfset ShowNewEtag=""> <cfset ShowOldEtag=""> <cfif form.Etag is ""> <cfset ShowNoEtag="checked"> <cfelseif form.Etag is "NewEtag"> <cfset ShowNewEtag="checked"> <cfset MyMode=MyMode&"NewEtag"> <cfelseif form.Etag is "OldEtag"> <cfset ShowOldEtag="checked"> <cfset MyMode=MyMode&"OldEtag"> </cfif> <cfparam name="form.Last" default=""> <cfset ShowNoLast=""> <cfset ShowNewLast=""> <cfset ShowOldLast=""> <cfset ShowBadLast=""> <cfif form.Last is ""> <cfset ShowNoLast="checked"> <cfelseif form.Last is "NewLast"> <cfset ShowNewLast="checked"> <cfset MyMode=MyMode&"NewLast"> <cfelseif form.Last is "OldLast"> <cfset ShowOldLast="checked"> <cfset MyMode=MyMode&"OldLast"> <cfelseif form.Last is "BadLast"> <cfset ShowBadLast="checked"> <cfset MyMode=MyMode&"BadLast"> </cfif> <cfparam name="form.Expires" default=""> <cfset ShowNoExpires=""> <cfset ShowNewExpires=""> <cfset ShowOldExpires=""> <cfset ShowBadExpires=""> <cfif form.Expires is ""> <cfset ShowNoExpires="checked"> <cfelseif form.Expires is "NewExpires"> <cfset ShowNewExpires="checked"> <cfset MyMode=MyMode&"NewExpires"> <cfelseif form.Expires is "OldExpires"> <cfset ShowOldExpires="checked"> <cfset MyMode=MyMode&"OldExpires"> <cfelseif form.Expires is "BadExpires"> <cfset ShowBadExpires="checked"> <cfset MyMode=MyMode&"BadExpires"> </cfif>
To display submitted checkbox values for on-off parameters (well, actually on-no), create "Show" variables that are either empty (so the box won't be checked) or the string "checked" (to check the box).
<cfparam name="form.Must" default="no"> <cfif form.Must is "on"> <cfset ShowMust="checked"> <cfset MyMode=MyMode&"Must"> <cfelse> <cfset ShowMust=""> </cfif> <cfparam name="form.Maxage" default="no"> <cfif form.Maxage is "on"> <cfset ShowMaxage="checked"> <cfset MyMode=MyMode&"Maxage"> <cfelse> <cfset ShowMaxage=""> </cfif> <cfparam name="form.Private" default="no"> <cfif form.Private is "on"> <cfset ShowPrivate="checked"> <cfset MyMode=MyMode&"Private"> <cfelse> <cfset ShowPrivate=""> </cfif> <cfparam name="form.Nostore" default="no"> <cfif form.Nostore is "on"> <cfset ShowNostore="checked"> <cfset MyMode=MyMode&"Nostore"> <cfelse> <cfset ShowNostore=""> </cfif> <cfparam name="form.Nocache" default="no"> <cfif form.Nocache is "on"> <cfset ShowNocache="checked"> <cfset MyMode=MyMode&"Nocache"> <cfelse> <cfset ShowNocache=""> </cfif> <cfparam name="form.Pragma" default="no"> <cfif form.Pragma is "on"> <cfset ShowPragma="checked"> <cfset MyMode=MyMode&"Pragma"> <cfelse> <cfset ShowPragma=""> </cfif> <cfparam name="form.Post" default="no"> <cfif form.Post is "on"> <cfset ShowPost="checked"> <cfset MyMode=MyMode&"Post"> <cfelse> <cfset ShowPost=""> </cfif>
Now use a cfoutput tag to expand the variables you've defined, and use tables to lay out the labels and controls in a form you can submit to modify a link. The reason for the groupings used here will become clear when you start experimenting.
<cfoutput> <form method="post"> <table> <tr><td colspan="4">Entity Tag (Etag):</td></tr> <tr><td><input type="radio" name="Etag" value="" #ShowNoEtag#></td> <td>None</td> <td><input type="radio" name="Etag" value="NewEtag" #ShowNewEtag#></td> <td>New</td> <td><input type="radio" name="Etag" value="OldEtag" #ShowOldEtag#></td> <td colspan="3">Old</td></tr> <tr><td colspan="4">Last-Modified Date:</td></tr> <tr><td><input type="radio" name="Last" value="" #ShowNoLast#></td> <td>None</td> <td><input type="radio" name="Last" value="NewLast" #ShowNewLast#></td> <td>New</td> <td><input type="radio" name="Last" value="OldLast" #ShowOldLast#></td> <td>Old</td> <td><input type="radio" name="Last" value="BadLast" #ShowBadLast#></td><td>Bad</td></tr> <tr><td colspan="4">Expires Date:</td></tr> <tr><td><input type="radio" name="Expires" value="" #ShowNoExpires#></td> <td>None</td> <td><input type="radio" name="Expires" value="NewExpires" #ShowNewExpires#></td> <td>New</td> <td><input type="radio" name="Expires" value="OldExpires" #ShowOldExpires#></td> <td>Old</td> <td><input type="radio" name="Expires" value="BadExpires" #ShowBadExpires#></td><td>Bad</td></tr> </table> <table> <tr><td>Must</td><td><input type="checkbox" name="Must" #ShowMust#></td> <td>Maxage</td><td><input type="checkbox" name="Maxage" #ShowMaxage#></td> <td>Private</td><td><input type="checkbox" name="Private" #ShowPrivate#></td></tr> <tr><td>Nostore</td><td><input type="checkbox" name="Nostore" #ShowNostore#></td> <td>Nocache</td><td><input type="checkbox" name="Nocache" #ShowNocache#></td> <td>Pragma</td><td><input type="checkbox" name="Pragma" #ShowPragma#></td></tr> <tr><td>Post</td><td colspan="5"><input type="checkbox" name="Post" #ShowPost#></td></tr> </table> <input type="submit" name="doit" value="Submit"> </form>
The link itself is rebuilt every time you submit the form. Provide instructions for the link. Close the cfoutput tag. Provide final instructions relating to the point of the process: to check for instant replay.
AFTER pressing submit and waiting for refresh, click this link:<br> <cfif len(trim(MyMode))> <a href="ubu.cfm?Mode=#MyMode#">#MyMode#</a> <cfelse> <a href="ubu.cfm">Plain</a> </cfif> </cfoutput> <p> After returning, click the link again.<br> Did the time change?
When "post" is involved, the test procedure is slightly different. Select some controls, including post, and see the link change. Then 1) try the link, 2) press the submit button on the lab page, 3) press the submit button on the lab page again, and 4) refresh the page. Notice the results and circumstances.
Before you begin, review checking and setting browser options.
Internet Explorer's default is to check for newer pages "Automatically". You'll also want to try "Every visit" - the most useful setting - and "Never" - a setting I have often encountered when working with users. From the browser menu, go to Tools..Internet Options..Settings to check and make these settings.
Netscape Navigator's default prior to brain-dead version 6 is to get a fresh page every time. To confirm this, go to Edit..Preferences..Advanced..Cache. Because this setting is usually correct - perhaps company IT folks don't mess with it - it's probably not worth your time to see the result of mal-adjusting Netscape to "Once per Session" or "Never".
Record the Web server you're using. My personal Web server uses HTTP/1.0, the older Web protocol that ignores cache-control directives. My Web host's server uses HTTP/1.1, the newer Web protocol that sometimes obeys them.
Note whether you're using https (secure) or http (the usual); because, this should also (in theory) cause your results to vary.
Finally, if you know that your browser uses a proxy server, note that too. Browse the page from another location (perhaps your home) where the browser isn't set to use a proxy server to see under what circumstances this makes a difference.
To recap, here's the list of things you'll want to take into account. (A spreadsheet is helpful here.)
Problems and their solution varied as shown below.