De browser-cache omzeilen
Door Phil Paxton
27 november 2000
In het kort:
De volgende serie opdrachten moeten bovenaan in de ASP pagina staan om ervoor te zorgen dat de pagina
niet wordt opgeslagen in de cache van de browser.
<%
Response.Expires = 60
Response.Expiresabsolute = Now() - 2
Response.AddHeader "pragma","no-cache"
Response.AddHeader "cache-control","private"
Response.CacheControl = "no-cache"
%>
Response.Expires = 60
Laat de pagina over 60 seconden verlopen. Khin Zaw heeft op de
ASP Advanced Mailinglist (US)
research gepost naar aanleiding van contacten met experts van de interne werking van IIS. Hieruit is gebleken
dat deze opdracht niet erg betrouwbaar is en vaak zelf een negatief nummer zou moeten bevatten om te werken.
Response.Expiresabsolute = Now() - 2
Hierdoor verloopt de pagina 48 uur geleden. Dit houdt dus ook rekening met het tijdsverschil tussen systemen in
verschillende tijdszones.
Response.AddHeader "pragma","no-cache"
Response.AddHeader "cache-control","private"
Response.CacheControl = "no-cache"
Deze code komt uit een Microsoft Knowledgebase artikel. Hoewel de code correct is, zijn sommige uitspraken
in het artikel zelf onjuist.
Zie voor meer informatie:
http://support.microsoft.com/support/kb/articles/q189/4/09.asp?FR=0
http://support.microsoft.com/support/kb/articles/q172/8/96.asp?FR=0
http://support.microsoft.com/support/kb/articles/q165/1/50.asp?FR=0
Als de technieken hierboven niet werken, kun je een 'cache-buster' gebruiken. Zo'n cache-buster zorgt ervoor dat
alle URLs altijd uniek zijn.
<a href=whatever.asp?Nocache=<%=rnd()%>>
of
<a href=whatever.asp?Nocache=<%=server.URLencode(now())%>>
Belangrijk om te onthouden is dat Netscape pagina's blijft cachen, zelfs als alle caching uitgezet is. Tot en
met versie 4.5 (op moment van schrijven) was dit het geval en er is weinig aanleiding om aan te nemen dat dit in
latere versies niet ook het geval is (of zal zijn).
Als je denkt later nog eens met de browser cache te maken te krijgen, is het slimmer om van te voren hier
rekening mee te houden. Om in een middelgrote applicatie de eerste code aan elke pagina toe te voegen is niet
zo'n probleem, maar achteraf de cache-buster toevoegen kost behoorlijk wat extra tijd. Ik gebruik daarom zelf nooit
Response.Redirect, behalve in voorbeeld code op mailinglists (eigenlijk geldt dit ook voor Response.Write,
omdat ik gebruik maak van de Display() en HTML() functies mijn Utilities-Form.inc library). In al mijn code
gebruik ik Redirect(NieuweURL), waarbij de Redirect functie er als volgt uit ziet:
Function Redirect(NieuweURL)
If Not IsEmpty(NieuweURL & "") Then
Dim QuestionMark
QuestionMark = Instr(NieuweURL, "?")
If QuestionMark = 0 Then
Response.Redirect NieuweURL & "?" & NoCacheURL()
Response.End
Else
Response.Redirect NieuweURL & "&" & NoCacheURL()
Response.End
End If
End If
End Function
and NoCacheURL looks like this:
Function NoCacheURL()
On Error Resume Next
Randomize
'Randomize niet nodig als je Now() gebruikt
NoCacheURL = "NoCache=" & Server.URLEncode(rnd)
'of NoCacheURL = "NoCache=" & Server.URLEncode(Now())
End Function
Ik heb gemerkt dat ik over het algemeen een iets andere aanpak heb dan de meeste mensen (soms beter, soms slechter,
maar over de hele gewoon anders). Ik heb een aantal kleine functies door mijn applicatie(s) met een aantal
#include statements. Dit mag misschien overkill lijken, maar realiseer je dat de browser cache hardnekkig is
en in een script omgeving erg frusterende resultaten kan opleveren. Een cache is heel handig voor pure HTML,
omdat het de server ontlast. Voor scripts met databases of tijd-gebaseerde applicaties is het niet ongewoon dat
er rare dingen door gebeuren.
Een leuk voorbeeld is een winkelwagentje... de volgende dingen zijn niet ongewoon:
- alle gegevens ineens "kwijt" zijn
- verwijderde items die ineens terug zijn
- nieuwe order laat items uit oude order zien
De eerste keer dat je er mee te maken krijgt, kun je er behoorlijk gek van worden. Als je er echter zelf niet
in je code wat aan doet, doen de gebruikers het voor je (door niet meer terug te komen). Je kunt in IIS caching
uitzetten voor de applicatie, maar firewalls en proxies kunnen ook een pagina in hun cache opslaan. Stel dat
een gebruiker de browser cache aan heeft staan en achter een of meerdere firewalls of proxy servers zit, die
allemaal gekocht zijn met het idee de zaak te versnellen door pagina's in de cache op te slaan... dan kun je
er niet vanuit gaan dat alles zomaar goed gaat en zul je de server(s) moeten vertellen dat ze de pagina's
niet in de cache mogen opslaan.
Veel bladen voor eind-gebruikers benadrukken nog steeds de voordelen van een cache, waaruit blijkt dat ze
nog steeds denken in een wereld waar alleen HTML bestaat, en geen applicaties. Script en cache gaan zelden goed
samen, ze zijn meestal als water en vuur: beide hebben hun doel, maar zelden samen.
Je bent altijd beter af als je altijd zorgt dat er niet gecached wordt. Dit kost weliswaar wat van de
server-prestaties, maar dat is beter dan dat je applicatie ineens op 'mysterieuze' wijze niet doet wat
er gevraagd wordt.
© Charles Carroll
(vertaling copyright ASPNL)
|