ASPNL logo (1 kb)
Saturday, February 04, 2012




Microsoft MVP

.NET Codewise Community
<< vorige | overzicht | volgende >>

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)

<< vorige | ^ naar boven | overzicht | volgende >>
copyright 2000-2007 ASPNL