|
Cache No More by Phil Paxton and John Sheppard
Page Cache Prevention Basics
Here are the the commands to place at the top of
your ASP scripts to ensure that the page is not cached:
<%
Response.Expires = 60
Response.Expiresabsolute = Now() - 1
Response.AddHeader "pragma","no-cache"
Response.AddHeader "cache-control","private"
Response.CacheControl = "no-cache"
%>
Response.Expires = 60
is said to expire at 60 seconds, not 0. Also, Khin Zaw (from
/asplists/aspadvanced.asp) has posted research from time spent with some IIS internals experts
revealing this can be a very touchy parameter to rely upon and usually requires a rather
"large" negative number or pedantically, that would be a very small number).
Response.Expiresabsolute=Now()-2
(my own creation) says "expire this page
48 hours ago", allowing for time
differences, rather than specify a static date. If your page is being viewed by
a browser in a very different time-zone it
Response.AddHeader "pragma","no-cache"
Response.AddHeader "cache-control","private"
Response.CacheControl = "no-cache"
their use originates rom an MS KB article. The code is correct but there are some incorrect
statements in the article itself.
Some related KB articles include:
<http://support.microsoft.com/?kbid=189409>
<http://support.microsoft.com/?kbid=172896>
<http://support.microsoft.com/?kbid=165150>
John Shepard writes us... "Use no-store, instead of no-cache."
The only way to prevent the user from using the back button after they have logged out is to set:
<%
Response.AddHeader "Pragma", "no-store" 'SSL: prevent cache, however Firefox will not cache SSL with Cache-Control: no-cache or no-store.
Response.Cache-Control = "no-store" 'HTTP prevent back button
Response.Expires = -1
%>
Resources:
HTTP/1.1: Header Field Definitions: Cache-Control <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9>
Firefox 1.5 caching <http://developer.mozilla.org/en/docs/Using_Firefox_1.5_caching>
Prevent caching when you download active documents over SSL <http://support.microsoft.com/?kbid=815313>
Disable Mozilla (Gekco) from caching pages <http://forums.aspfree.com/showpost.php?p=230022&postcount=28>
Should: Ought to, but not necessarily will.
CacheBuster Tactics
If the above techniques do not work in every instance, a
"cache-buster" can be employed.
<a href=whatever.asp?Nocache=<%=rnd()%>>
or
<a href=whatever.asp?Nocache=<%=server.URLencode(now())%>>
Another thing to remember: Netscape will continue to cache, even if you turn all
caching off. This behavior persisted through 4.5 PR1, PR2, and now in the released version
of 4.5.
CacheBuster Simplified Via A Library
If you fear you might have to deal with caching later, you might want to build
contingencies into your app as you go. Retrofitting #5 throughout even a medium-sized app
would take a rather sizeable effort. You could retrofit #1-#4 (inclusive) rather quickly
with a single pass through the application, but #5 takes a lot of extra effort. And to
that end, I don't ever Response.Redirect anywhere in my code except sample code I post to
the lists (then again, the only time I use Response.Write is to the list because I rely on
my Utilities-Form.inc library (see a sample of such a library for Display() and HTML()). Everything is Redirect(NewURL)
where the Redirect function looks like this:
Function Redirect( NewURL )
'
If Not IsEmpty( NewURL & "" ) Then
Dim QuestionMark
'
QuestionMark = Instr( NewURL, "?" )
'
If QuestionMark = 0 Then
Response.Redirect NewURL & "?" & NoCacheURL()
Response.End
Else
Response.Redirect NEWURL & "&" & NoCacheURL()
Response.End
End If
End If
'
End Function
and NoCacheURL looks like this:
Function NoCacheURL()
'
On Error Resume Next
'
Randomize
' Randomize not needed if you use Now()
'
NoCacheURL = "NoCache=" & Server.URLEncode(rnd)
'
' or NoCacheURL = "NoCache=" & Server.URLEncode(Now())
' per Bill
'
End Function
I've learned that I approach things a little differently (sometimes better, sometimes
worse, but overall, just differently) and have gotten used to a bunch of tiny little
routines scattered throughout my app with a bunch of #include statements. Some of this
might seem like overkill, but you have to understand just how pervasive and frustrating
caching can be in a scripted app environment. Caching is great for pure HTML because it
reduces server overhead. But if you do much scripting against databases, or time-based
functions, it's not unusual to see rather bizarre things happen. Shopping cart
applications will suddenly "lose" items already purchased; they'll
"regain" items previously deleted. Starting a new order with an assigned
"OrderID" (to use as a temporary confirmation number for the sake of the user)
will suddenly show items from a previous order. It can be maddening the first time you
have to deal with it. And if you don't deal with it head-on in your code, your users may
be dealing with it for you -- you can turn caching off for your application in IIS
[itself], but what if you are behind a firewall or proxy server which does caching for
you? Or, if the user has caching turned on in their browser or they could be behind one or
more layers of firewalls or proxy servers, all of which have been sold under the premise
of delivering better performance through caching? Unless and until you can control every
layer of access to your app, telling your server not to cache isn't a solution because
requests may not be making it back to said server.
End-user magazines continue to extol the benefits of caching, demonstrating they are still
thinking of an HTML-only world. Scripting and caching are rarely synergistic and are
almost always like oil & water: both have a purpose, but rarely together.
You're almost always better off to just turn all caching off and take the performance hit
than to try & retrofit all of this into an app which "mysteriously" begins
misbehaving.
 |  |  |
 |
There are many worthy charities!!. But perhaps help starving children in Africa or South America AND help Charles too.
a $5 tip buys him lunch at McDonalds,
a $20 tip buys his kid Hitoshi a new computer game,
a $39 tip buys his daughter Michiko a few nice outfits.
See our donor list.
|  |
 |  |  |
|
|
|
|