http-headers: caching

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • dineke
  • Registratie: Januari 2009
  • Laatst online: 14-09-2015
Voor de website van mijn bedrijf wil ik de http-headers van de pagina's die we verzenden finetunen op het gebied van caching. Maar:

Wij hadden geen restricties, maar nu hebben we een paar keer een bug gehad waardoor gebruikers elkaars persoonlijke pagina's toegestuurd kregen. Dit bleek te komen door proxy-caching: de verschillende gebruikers waren afkomstig van dezelfde ip en hadden dezelfde useragent.

Dit willen we zeer zeker niet (op persoonlijke pagina's kan vertrouwelijke informatie staan), en om deze reden heb ik 'cache-control=private' in de HTTP-Headers gezet (dan wordt shared caching niet meer toegestaan).

Dat gaat prima in firefox, maar in IE betekent dit dat als een user een post doet, vervolgens verder klikt en weer back gaat hij een "Pagina is verlopen"-pagina krijgt.

Is er een manier om shared caching uit te schakelen zonder dit probleem?

Omdat ik zelf niet met IE werk weet ik niet of IE-gebruikers deze melding inmiddels heel vaak tegenkomen en eraan gewend zijn. Stel dat dat zo is kunnen we dit nadeel misschien accepteren.

Overigens hebben we ook waarden als max-age=0, Expires='Fri Jul 02 1999' , cache-control=must-revalidate uit- en aangedaan, maar alle combinaties bleven het 'pagina is verlopen'-probleem houden.

Ik hoop dat er iemand kan helpen! Alvast bedankt luitjes

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23:37

Janoz

Moderator Devschuur®

!litemod

dineke schreef op vrijdag 30 januari 2009 @ 14:33:
Dat gaat prima in firefox, maar in IE betekent dit dat als een user een post doet, vervolgens verder klikt en weer back gaat hij een "Pagina is verlopen"-pagina krijgt.
Op zich reageert IE in dit geval op de enige juiste manier. Een response gebaseerd op POST zou je niet zomaar nog een keer moeten kunnen doen. Dit is 1 van de grote verschillen tussen GET en POST. POST is niet idempotent. Dit wil (kort door de bocht) zeggen dat het niet veilig is om dat request zomaar meerdere keren uit te voeren.

Je moet je probleem niet oplossen in de headers, maar bij de POST. Als je de melding wilt voorkomen zul je moeten zorgen dat je niet dergelijke acties in de history van de browser op laat nemen. Dat klinkt heel ingewikkeld, maar in het kort komt het op de volgende twee stappen neer:

Gebruik GET voor idempotente acties.
Gebruik POST bij niet idempotente acties, maar laat deze als resultaat een header redirect sturen. Hierdoor wordt de postactie zelf niet in de history opgenomen en kan de gebruiker er gewoon met back langs klikken.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-09 16:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat gaat prima in firefox, maar in IE betekent dit dat als een user een post doet, vervolgens verder klikt en weer back gaat hij een "Pagina is verlopen"-pagina krijgt.
Ik dacht dat IE dat altijd deed na een POST, en dus niet zozeer alleen met cache-control=private? Ik zou er overigens niet zo zwaar aan tillen. Een POST actie is immers niet idempotent, dus het gedrag van IE is eigenlijk heel normaal. En als oud IE gebruiker ben ik dit soort dingen vaak tegengekomen.

En goede manier om dit af te vangen door op een POST request te reageren met een doorverwijzing. De browser doet vervolgens een GET, en dus kun je gewoon heen en weer navigeren.

.edit: GMTA :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • dineke
  • Registratie: Januari 2009
  • Laatst online: 14-09-2015
Bij onze huidige applicatie, zonder cache-control, zijn er niet dergelijke pagina's, en het was voor ons belangrijk dat de gebruiker geen 'gekke dingen ziet'.

Maar het niet krijgen van andermans pagina's is zeker belangrijker, dus de cache-control=private gaat er nu meteen op, en dan gaan we daarna kijken of we met doorverwijzingen het leed kunnen verzachten. Maar het is dus een vorm van leed die de IE-gebruiker wel kent, dat scheelt :-)

Dank voor de hulp!

Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Doe dan trouwens wel een 302 redirect, omdat een 301 een permanente redirect is. In het laatste geval zou de browser de redirect in theorie moeten bewaren en bij iedere volgende bezoek aan die pagina direct doorgaan naar de redirect, zonder de post te doen.

302 is hier dus de correcte, en is bij de meeste talen volgens mij de standaard redirect, maar het kan geen kwaad om dat ff te verifiëren ;)

日本!🎌


Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Janoz schreef op vrijdag 30 januari 2009 @ 14:49:
[...]

Op zich reageert IE in dit geval op de enige juiste manier. Een response gebaseerd op POST zou je niet zomaar nog een keer moeten kunnen doen.
Ik snap het niet helemaal. Het gaat er hier toch om dat je via een back button een pagina die ooit werd gerenderd na een POST gewoon weer te zien krijgt? Waarom zou je die niet meer mogen zien?

Stel nou eens voor dat ik een pagina krijg na een POST met daarom een hyperlink. Ik click op deze hyperlink en via een GET request kom ik op de volgende pagina. Als ik nu op de back button click zou IE zeggen dat de pagina verlopen is neem ik aan. Kennelijk mag ik die pagina dus niet meer zien.

Maar als ik nu in plaats van direct op de link te clicken met de rechter muis knop op die link click en zeg "open in new tab", dan kan ik daarna door op de eerste tab te clicken die oorspronkelijk pagina toch ook weer zien? Nu zegt IE dan hopelijk niet 'pagina verlopen'.

Dat lijkt me een beetje inconsequent, maar misschien begrijp ik het probleem niet helemaal. Als Firefox en Safari het niet doen, wat toch serieuze browsers zijn, en IE wel, wat vaak een iets minder serieuze browser is, dan vraag ik me toch af wie er nu echt gelijk heeft hoor.
Gebruik GET voor idempotente acties.
Gebruik POST bij niet idempotente acties, maar laat deze als resultaat een header redirect sturen. Hierdoor wordt de postactie zelf niet in de history opgenomen en kan de gebruiker er gewoon met back langs klikken.
redirect-after-post is een goed paradigma ja, maar bij gebruik van diverse web frameworks is de tip om POST voor niet idempotente acties te gebruiken en get voor idempotente acties niet helemaal triviaal. Zowel Java EE als ASP.NET gebruiken standaard POST voor van alles en nog wat om hun viewstate te behouden. Hoewel goed bedoeld zijn GET en POST typisch voor het oorspronkelijke doel van HTTP en HTML bedoeld. In tussen zijn we massaal desktop applicaties aan het porten en in het HTTP protocol aan het proppen. In een desktop applicatie druk ik op een knop waaraan diverse action listeners hangen. Enkele van die kunnen potentieel een niet idempotente actie doorvoeren. De rendering van die knop weet dat niet (altijd) van te voren.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 19:56

MueR

Admin Tweakers Discord

is niet lief

flowerp schreef op zaterdag 31 januari 2009 @ 00:57:
Ik snap het niet helemaal. Het gaat er hier toch om dat je via een back button een pagina die ooit werd gerenderd na een POST gewoon weer te zien krijgt? Waarom zou je die niet meer mogen zien?
Omdat er een aantal acties gedaan kunnen zijn met het formulier wat jij ingestuurd hebt, zoals het plaatsen van een order. Je voorbeeld van tabs is loos, dan bekijk je de pagina niet opnieuw (refresh), maar je houd hem gewoon in je browser open. Gebeurt verder niks. Mocht die POST voor de order opnieuw worden uitgevoerd, krijg je ineens een vervuilde order database.
redirect-after-post is een goed paradigma ja, maar bij gebruik van diverse web frameworks is de tip om POST voor niet idempotente acties te gebruiken en get voor idempotente acties niet helemaal triviaal. Zowel Java EE als ASP.NET gebruiken standaard POST voor van alles en nog wat om hun viewstate te behouden. Hoewel goed bedoeld zijn GET en POST typisch voor het oorspronkelijke doel van HTTP en HTML bedoeld.
Tja, de vraag is dan of dat belangrijke zaken zijn die ASP en Java EE in die POSTs gooien. Dat het niet netjes is, true. Je moet alleen niet een zwakte van een programmeur afschuiven op een framework hoor.
In een desktop applicatie druk ik op een knop waaraan diverse action listeners hangen. Enkele van die kunnen potentieel een niet idempotente actie doorvoeren.De rendering van die knop weet dat niet (altijd) van te voren.
En het is aan jou om die acties af te vangen, te behandelen en daarna ervoor te zorgen dat je niet nogmaals die actie doet. Geef niet de schuld aan de browser, want dit hoor je zelf netjes op te lossen.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
MueR schreef op zaterdag 31 januari 2009 @ 07:34:
[...]
Omdat er een aantal acties gedaan kunnen zijn met het formulier wat jij ingestuurd hebt, zoals het plaatsen van een order. Je voorbeeld van tabs is loos, dan bekijk je de pagina niet opnieuw (refresh), maar je houd hem gewoon in je browser open. Gebeurt verder niks. Mocht die POST voor de order opnieuw worden uitgevoerd, krijg je ineens een vervuilde order database.
Maar je snapt niet wat ik bedoel. Ik heb het helemaal niet over het opnieuw uitvoeren van de POST. Ik wil alleen lokaal de HTML die geserveerd was als het gevolg van de POST weer zien. Er vind in mijn voorbeeld geen enkele server communicatie plaats en dus is een vervuilde orde database niet van toepassing.

Een voorbeeld dan maar

code:
1
2
3
4
T1 POST /pagina.html
T2 Response = "abc"
T3 GET /andere_pagina.html
T4 Response = "xyz"


Nu zit ik op dit moment naar "xyz" op mijn scherm te kijken. Opeens bedenk ik me, zag ik nu daarnet "abc" staan op mijn scherm of "abcd"? Ik click dus op de back button en verwacht dat "abc" uit mijn lokale cache geserveerd wordt.

Dat is precies wat Firefox doet. Waar is die vervuilde order data base nu? Als de response "abc" in de cache staat dan vind er geen server communicatie plaats en zal die order dus niet overnieuw geplaatst worden. Pas als ik de page probeer te refreshen zal dat gebeuren, en dan verwacht ik ook een waarschuwing. Als ik de pagina alleen weer wil bekijken (als ware het een statisch plaatje) dan zie ik er geen problemen in.
En het is aan jou om die acties af te vangen, te behandelen en daarna ervoor te zorgen dat je niet nogmaals die actie doet. Geef niet de schuld aan de browser, want dit hoor je zelf netjes op te lossen.
Maar lieve schat, je kunt alle acties af vangen die je wilt, maar je moet toch van te voren weten of je die knop via POST of GET laat communiceren met je server? Alleen in een applicatie waarbij listeners progammatich en dynamisch aan een knop gekoppeld worden weet je dat niet altijd van te voren! Je zou een protocol kunnen verzinnen waarbij je niet een addActionListener hebt maar een addIdemPotentActionListener en een addNonIdemPotentActionListener. Als de knop dan ook maar 1 NonIdemPotentActionListener hebt rendert ie die knop voor een POST anders een GET. Geen 1 van de bestaande frameworks doen dat nu echter.

[ Voor 18% gewijzigd door flowerp op 31-01-2009 10:49 ]

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

Verwijderd

code:
1
2
3
4
T1 POST /pagina.html
T2 Location: /andere_pagina.html
T3 GET /andere_pagina.html
T4 Response = "xyz"

De client krijgt helemaal geen output te zien naar aanleiding van die POST request. Het enige dat in een HTTP body van de response op die POST request zou kunnen staan is een HTML equivalent van een pagina die vertelt waarheen geredirect moet worden als de client geen Location headers volgt.

[ Voor 16% gewijzigd door Verwijderd op 31-01-2009 17:37 ]


Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Verwijderd schreef op zaterdag 31 januari 2009 @ 17:36:
De client krijgt helemaal geen output te zien naar aanleiding van die POST request. Het enige dat in een HTTP body van de response op die POST request zou kunnen staan is een HTML equivalent van een pagina die vertelt waarheen geredirect moet worden als de client geen Location headers volgt.
Wat is dat nou weer voor een onzin? Een response op een POST kan gewoon een volledige HTML pagina zijn hoor! Als dat niet zo was geweest dat was deze hele topic er nooit geweest,

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

Verwijderd

flowerp schreef op zaterdag 31 januari 2009 @ 20:33:


Wat is dat nou weer voor een onzin? Een response op een POST kan gewoon een volledige HTML pagina zijn hoor! Als dat niet zo was geweest dat was deze hele topic er nooit geweest,
Ja, maar dat wil de topicstarter dus niet :z

Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Verwijderd schreef op zaterdag 31 januari 2009 @ 20:52:
[...]
Ja, maar dat wil de topicstarter dus niet :z
Klaarblijkelijk, maar over welke schaal van bestaande software hebben we het? Ga jij die allemaal even omschrijven naar redirect-after-post? O-)

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 19:56

MueR

Admin Tweakers Discord

is niet lief

flowerp schreef op zaterdag 31 januari 2009 @ 10:45:
Maar lieve schat, je kunt alle acties af vangen die je wilt, maar je moet toch van te voren weten of je die knop via POST of GET laat communiceren met je server?
Je gaat mij vertellen dat je zelf niet weet hoe je software met zichzelf communiceert? Buzzword bingo is leuk, maar je hebt me er niet mee. Jij hoort altijd te weten welke knop wat doet, je schrijft de software immers.

[ Voor 6% gewijzigd door MueR op 02-02-2009 08:54 ]

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23:37

Janoz

Moderator Devschuur®

!litemod

flowerp schreef op zaterdag 31 januari 2009 @ 00:57:
[...]


Ik snap het niet helemaal. Het gaat er hier toch om dat je via een back button een pagina die ooit werd gerenderd na een POST gewoon weer te zien krijgt? Waarom zou je die niet meer mogen zien?
Het gaat hier om de back button icm een no caching header. De browser is dus verplicht om het request opnieuw uit te voeren. Daar komt juist de idempotentie om de hoek krijgen. Bij het opvragen van de inhoud van een gastenboek maakt dat niet uit, maar bij het opsturen van een machtiging juist weer wel.
Stel nou eens voor dat ik een pagina krijg na een POST met daarom een hyperlink. Ik click op deze hyperlink en via een GET request kom ik op de volgende pagina. Als ik nu op de back button click zou IE zeggen dat de pagina verlopen is neem ik aan. Kennelijk mag ik die pagina dus niet meer zien.
IE mag de pagina niet zomaar opnieuw opvragen. Aangezien hij hem (volgens de headers) ook niet uit zijn cache kan halen kan IE de pagina niet zomaar weergeven.
Maar als ik nu in plaats van direct op de link te clicken met de rechter muis knop op die link click en zeg "open in new tab", dan kan ik daarna door op de eerste tab te clicken die oorspronkelijk pagina toch ook weer zien? Nu zegt IE dan hopelijk niet 'pagina verlopen'.
[...]
Dat lijkt me een beetje inconsequent, maar misschien begrijp ik het probleem niet helemaal. Als Firefox en Safari het niet doen, wat toch serieuze browsers zijn, en IE wel, wat vaak een iets minder serieuze browser is, dan vraag ik me toch af wie er nu echt gelijk heeft hoor.
Ik heb het dit weekend even geprobeert, en ook bij Firefox krijg ik de vraag of ik de postgegevens opnieuw wil versturen.
redirect-after-post is een goed paradigma ja, maar bij gebruik van diverse web frameworks is de tip om POST voor niet idempotente acties te gebruiken en get voor idempotente acties niet helemaal triviaal. Zowel Java EE als ASP.NET gebruiken standaard POST voor van alles en nog wat om hun viewstate te behouden. Hoewel goed bedoeld zijn GET en POST typisch voor het oorspronkelijke doel van HTTP en HTML bedoeld. In tussen zijn we massaal desktop applicaties aan het porten en in het HTTP protocol aan het proppen. In een desktop applicatie druk ik op een knop waaraan diverse action listeners hangen. Enkele van die kunnen potentieel een niet idempotente actie doorvoeren. De rendering van die knop weet dat niet (altijd) van te voren.
Dat is dan ook nog altijd 1 van mijn grotere bezwaren tegen bv JSF.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1