| Autor |
Beitrag |
Gausi
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Sa 04.10.08 17:21
Ich hab da mit den Indys einen kleinen Webserver gebaut, bei dem ich noch ein kleines Problem habe.
Und zwar ändern sich die Daten, die der Server bei Anfrage einer speziellen Seite liefern soll, recht schnell. Der Browser benutzt aber manchmal/oft die alte Seite, die er wohl aus dem Cache nimmt, wenn ich über einen Link auf einer anderen Seite die Seite wieder aufrufe.
Wie kann ich den Browser dazu bringen, dass er bei Klick auf einen Link die Seite dahinter neu lädt und nicht die Daten aus dem Cache nimmt?
_________________ We are, we were and will not be.
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Sa 04.10.08 17:26
Gibt es keinen Befehl, um den Cache zu lehren 
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
Gausi 
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Sa 04.10.08 17:33
Naja, ich will ja nicht den Cache leeren. Ich will nur, dass der Browser irgendwie merkt, dass da was neues hinter dem Link steckt.
Beispiel: Wenn ich hier im posting.php oben auf den Link zu delphi-forum.de/index.php klicke, dann lädt mein Browser die Startseite vom Forum neu, obwohl ich grade eben noch dadrauf war. Wie kann ich dieses Verhalten mit den Indys nachbauen?
_________________ We are, we were and will not be.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 04.10.08 18:21
Du musst in der Seite ein Pragma: no-cache mitsenden, um dem Browser mitzuteilen, dass die Seite nicht gespeichert werden soll.
Alternativ kannst Du einen Last-Modified-Header senden, damit der Browser bei Dir nachfragt, wann sich die Seite geändert hat und ob er den Inhalt komplett neu laden soll.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 04.10.08 18:23
Moin!
Gausi hat folgendes geschrieben : | | Ich will nur, dass der Browser irgendwie merkt, dass da was neues hinter dem Link steckt. |
Ich hab das hier in einem älteren PHP-Projekt gefunden:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| <?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Datum aus Vergangenheit header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // immer geändert header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1 header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); // HTTP/1.0 | Vielleicht kommst du damit weiter.
Muss aber im Commandhandler in die Headerdaten gesetzt werden, nicht in den Content, IIRC.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 04.10.08 18:33
Narses hat folgendes geschrieben : | Moin!
Gausi hat folgendes geschrieben : | | Ich will nur, dass der Browser irgendwie merkt, dass da was neues hinter dem Link steckt. | Ich hab das hier in einem älteren PHP-Projekt gefunden:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| <?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Datum aus Vergangenheit header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // immer geändert header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1 header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); // HTTP/1.0 | Vielleicht kommst du damit weiter.  |
@ Narses: Das sind exakt jegliche Header, die man benötigt:
- Expires sagt an, wann die Gültigkeit der ausgelieferten Seite endet. Da diese Zeit Client-Seitig ausgewertet wird, muss man hier oftmals ein Datum in der Vergangenheit angeben, um eine sofortige Revalidierung zu erreichen. Laut RFC würde hier aber i.d.R. ein Datum in der Zukunft stehen, wann die präsentierte Information abläuft.
- Last Modified: Datum der letzten Änderung (Laut Server-Zeit). Hier kann z.B. das Datum der letzten Aktualisierung deiner Daten stehen.
- Cache-Control: Sollte IMHO klar sein.
- Pragma: Die obsolete Version des Cache-Control-Headers. MUSS Aus Kompatibilitätsgründen angegeben werden, um alle Browser abzudecken.
Zusätzlich kann man auch noch mit ETags rumspielen, das ist aber i.d.R. nicht nötig.
Narses hat folgendes geschrieben : | Muss aber im Commandhandler in die Headerdaten gesetzt werden, nicht in den Content, IIRC.
cu
Narses |
Der header-Befehl von PHP erzeugt einen Antwort-Header, ist doch klar, dass der nicht im Content-Bereich erscheint. Man kann die oben gesendeten Werte über entsprechende META-http-equiv-Angaben auch noch mal im ausgelieferten Dokument verankern.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Gausi 
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Sa 04.10.08 18:47
Ok, das ist schonmal was. Mit
AResponseInfo.CustomHeaders.Add('Cache-Control: no-store, no-cache, must-revalidate'); scheint das schon zu funktionieren. Sind die anderen Header unbedingt nötig? Ok, die alte Version des Cache-Dingens sehe ich noch ein, aber sind Expires und Modified auch nötig?
Wäre egal, wenn ich das auch noch einfügen müsste, jetzt geht es ums Verstehen. 
_________________ We are, we were and will not be.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 04.10.08 19:04
Der Expires-Header gibt wie oben geschrieben an, bis wann eine Seite gültig ist. Angenommen, man erlaubt dem Browser die Seite zu cachen, dann würde der Browser erst nach erreichen des Expires-Headers wieder beim Server nachfragen, ob sich was geändert hat. Nun gibt es bei dieser Anfrage zwei Möglichkeiten:
- Der Browser sendet den alten Last-Modified-Header in einer "If-Modified-Since"-Anfrage (oder den Expires-Header, wenn kein Last-Modified vorhanden ist) und erfährt, dass sich trotz Ablauf der Antwortgültigkeit nichts geändert hat: Der Browser zeigt seinen bisherigen Content weiter an, fragt aber bei jedem weiteren Aufruf beim Server immer erneut an, wann sich wieder was geändert hat. Der Server sendet in seiner Antwort KEINEN Content-Bereich mit, da der Client diesen ja eh bereits kennt
- Der Browser sendet einen If-Modified-Since-Header und bekommt vom Server mitgeteilt, dass eine neuere Version verfügbar ist. In diesem Fall sendet der Server auch gleich die neue Version des Dokuments. Der Browser übernimmt diese Information in seinen Cache, sofern er erlaubt ist, dies zu tun.
Warum sollte man nun diese Header nutzen: Da man im Idealfall Content sparen kann UND die Rechenzeit, um die Antwort zu generieren. Daher sollte man, wenn ein Neuaufbau der Seite nur in unregelmäßigen Abständen nötig ist, das Caching von HTTP nutzen, wenn dies möglich ist ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Gausi 
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Sa 04.10.08 19:29
Um den Traffic gehts mir eher weniger. Das sind in der Regel weniger als 10kb, und wenn man halbwegs was in der Birne hat, nutzt man die Funktion nur im LAN. Der Zugriff nur nach Passworteingabe tut da auch noch was bei.
Um die Serverleistung auch nicht - das Ding ist sowieso eigentlich für nur einen Nutzer ausgelegt - wäre vollkommen unsinnig, wenn 10 Leute gleichzeitig an dem Player rumfummeln.
Und zu deinen Erklärungen: Der untere Teil in Narses' Auflistungen verbietet dem Browser (so wie ich das verstehe), den Cache zu nutzen. - Wozu also dann die Modified/Expires-Header?
Oder sind das einfach zwei Möglichkeiten, das Problem zu lösen? Das eine etwas eleganter, das andere mit Gewalt?
_________________ We are, we were and will not be.
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: Sa 04.10.08 19:37
phpBB3 regelt den Download der Anhang-Dateien so:
PHP-Code: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| $last_load = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime(trim($_SERVER['HTTP_IF_MODIFIED_SINCE'])) : false; if (strpos(strtolower($browser), 'msie 6.0') === false) { if ($last_load !== false && $last_load <= $stamp) { if (@php_sapi_name() === 'CGI') { header('Status: 304 Not Modified', true, 304); } else { header('HTTP/1.0 304 Not Modified', true, 304); } header('Pragma: public'); header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000)); exit(); } else { header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $stamp) . ' GMT'); } |
Das mit IE6 verstehe ich nicht, wahrscheinlich kann der das ganze nicht, aber sonst ist der Code ganz verständlich. Das exit(); heißt, dass die Datei nicht versendet werden soll, danach kommt nämlich der eigentliche Dateitransfer.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 04.10.08 19:48
@Yogu: Der IE6 hat einen Bug bei der Behandlung der Cache-Header, wenn nicht die richtigen Statuscodes gesendet werden, daher die Sonderbehandlung. Da wird nix andres gemacht, als explizit einen HTTP-Status 304 zu senden, der besagt, dass sich nix verändert hat.
@Gausi: Wieso nicht  Collaborative Music Listening
Zu der Geschichte Expires vs. Cache Control:
Übergeordnet sind zuerst einmal die Pragma- und Cache-Control-Direktiven, die angeben ob überhaupt, und wenn ja, was gecacht werden darf. Darauf aufbauend müssen, wenn der Cache verwendet wird, informationen über die Gültigkeitsdauer, bzw. evtl. nötige Updates eingetragen werden, was mit Hilfe der Last-Modified\Expires-Header geschieht.
Nun zum Problem: Leider interpretieren nicht alle Browser alle Header immer unter allen Umständen korrekt (siehe IE6  ). Daher sollte man i.d.R. alle Header senden, um ein Fallback zu haben, wenn die Interpretation eines einzelnen Header-Wertes einmal fehlschlagen sollte.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|