Inspiriert durch den Thread Beitrag "Kann man ein Tablet als Display benutzen?"
habe ich ein älteres Projekt wieder aktiviert, wo ich am Cache
hängengeblieben bin. Die Visualisierung ist in SpiderBasic geschrieben
(Manometer.sb) und soll auf zwei Tablets übereinander Geräte in einem
Führerstand anzeigen für die Steuerung der Modelleisenbahn. Beim Starten
des .html im .zip kann die Ansicht ausgewählt werden, oben
(manometer_oben_Ansicht.png) oder unten. Alles im .zip läuft auf einem
Webserver (HFS-File-Server, https://www.rejetto.com/hfs/) und wird im
Intranet bereitgestellt.
Mein Ansatz war, die aktuellen Daten in einer Datei (manometer.txt im
.zip) bereitzustellen, und die "App" lädt die alle 500ms nach. Das geht.
Aber nicht immer, und ausgerechnet auf den Tablets (Asus K00F, 10")
nicht! Es scheint der (Browser-?)Cache zu sein. Nach dem ersten Start
zeigt er einfach stur die zum ersten Mal eingelesenen Daten an. Im
Browser (Chrome) auf dem lokalen Rechner wird es (manchmal mit
Verzögerung) angezeigt, auf dem Smartphone immer fast ohne Verzögerung.
Auch Einfügen von folgenden Zeilen im Header vom .html hilt nichts: 1 | <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
| 2 | <meta http-equiv="Pragma" content="no-cache" />
| 3 | <meta http-equiv="Expires" content="0" />
|
Kann ich das Problem irgendwie durch Umgehung des Caches lösen oder bin
ich auf dem völlig falschen Dampfer?
Gruss Chregu
Für sowas wurden eigentlich Webservices erfunden.
https://de.wikipedia.org/wiki/Webservice
Die Header bringen nichts, das HTML darf ja auch ruhig im Cache bleiben.
dein "manometer.txt" darf nicht im Cache liegen, d.H. die Datei braucht
entsprechende Header.
Und, da es kein HTML ist: Es braucht die Header "richtig", also als
HTTP-Header, nicht als "HTTP-Equiv"-Workaround.
alternative:
Statt
>> ReadFile(0, "manometer.txt", @ReadCallback())
eben "manometer.txt?x=123123123" laden (also jeden Aufruf mit anderer
Zufallszahl)
Εrnst B. schrieb:
> eben "manometer.txt?x=123123123" laden (also jeden Aufruf mit anderer
> Zufallszahl)
Du, das geht! Bin begeistert! Vielen Dank!
Habe Millisekunden seit Start genommen:
1 | ReadFile(0, "manometer.txt?x=" + Str(ElapsedMilliseconds()), @ReadCallback())
|
Gruss Chregu
Εrnst B. schrieb:
> dein "manometer.txt" darf nicht im Cache liegen, d.H. die Datei braucht
> entsprechende Header.
Könnte ich es einfach in ein HTML umbenennen und den Inhalt in ein
gültiges HTML-File machen und einfach den Inhalt parsen, oder geht das
wegen
Εrnst B. schrieb:
> Und, da es kein HTML ist: Es braucht die Header "richtig", also als
> HTTP-Header, nicht als "HTTP-Equiv"-Workaround.
nicht? Verstehe Deine Beschreibung nicht ganz.
Gruss Chregu
Christian M. schrieb:
> Verstehe Deine Beschreibung nicht ganz.
Jede Datei die vom Webserver ausgeliefert wird, wird mit diversen
HTTP-Headers ausgeliefert. z.B. "Cache-Control: no-cache" oder
"Content-Type: text/html".
Diese Headers sendet der Webserver, sie sind nicht Teil der Datei.
Nun gab es in der dunklen Anfangszeit des Internets gewisse Webserver
(hust Microsoft hust) und Hosting-Anbieter, die das Konfigurieren
dieser Header nicht erlaubt haben.
Das hat dann zu allerlei besch**** Workarounds geführt. Z.B. dazu, dass
Webbrowser den Inhalt der Datei nicht anhand des "Content-Type"-Headers
erkannt haben, sondern anhand Datei-Extensions in der URL oder den
ersten paar Bytes usw.
Oder eben, dass im speziellen Fall des Toplevel-HTML-Dokuments die
HTTP-Header auch innerhalb des HTMLs stehen können, per <meta
http-eqiv>.
Diese Workarounds haben dann zur nächsten Generation an Problemen und
Sicherheitslücken geführt, z.B. dass der Internet Explorer keine Dateien
herunterladen wollte, wenn ".htm" im Pfad stand, oder "Mime Confusion
Attacks"...
Dafür gab's dann die nächste Schicht Sonderlocken-Workarounds
drübergebügelt, z.B. "X-Content-Type-Options: nosniff"...
Also: Einfach "richtig" machen, und sich nicht auf irgendwelche
historisch bedingten Eigenheiten verlassen.
Christian M. schrieb:
> Könnte ich es einfach in ein HTML umbenennen und den Inhalt in ein
> gültiges HTML-File machen und einfach den Inhalt parsen
Das könnte in der Theorie und bei manchen Browsern funktionieren, hängt
aber davon ab, wie der Download intern implementiert ist.
falls per historischem "XMLHttpRequest": möglicherweise, eher nicht.
falls per modernerem "fetch": ziemlich sicher nicht.
falls per "iframe src": facepalm, aber geht möglicherweise.
Christian M. schrieb:
> Kann ich das Problem irgendwie durch Umgehung des Caches lösen oder bin
> ich auf dem völlig falschen Dampfer?
Websockets wären auch eine Möglichkeit, weiss gar nicht ob da die cache
header von http auch gültig sind oder es was ähnliches gibt, vermutlich
nicht. Aber dieses HFS-Dingens das du einsetzt unterstützt wohl keine
Websockets obwohl es auf node basiert das es normalerweise kann.
Aber der Hack oben reicht ja auch schon.
Christian M. schrieb:
> Könnte ich es einfach in ein HTML umbenennen und den Inhalt in ein
> gültiges HTML-File machen und einfach den Inhalt parsen,
Das könntest Du möglicherweise machen, aber es wäre nicht besonders
klug. Du könntest Deine "manometer.txt" ins JSON-Format (JavaScript
Object Notation) umwandeln und JavaScript das Parsen überlassen, siehe
dazu auch [1,2].
Bezüglich des Caching kannst Du Deinen HTTP-Header "Expires" auf "0"
setzen, siehe dazu [3]. Genauer gesagt, ist der Wert "0" ungültig und
sagt damit dem Webbrowser, daß die Gültigkeitsdauer des Dokuments
bereits abgelaufen ist und bei weiteren Anfragen erneut abgerufen werden
muß, anstatt es zu cachen.
Eine andere Alternative zur Cache-Kontrolle ist der ETag [4], das
funktioniert ähnlich wie die Methode zum Anhängen eines Strings an einen
GET-Request -- wie Ernst es in [5] vorgeschlagen hat -- jedoch als
HTTP-Header.
Eine (wie ich finde) lesbare Übersicht zum Thema Caching findest Du
ansonsten beim Mozilla-Projekt unter [6]. Viel Erfolg! :-)
[1] https://www.w3schools.com/js/js_json_parse.asp
[2]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
[3]
https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/Expires
[4] https://de.wikipedia.org/wiki/HTTP_ETag
[5] Beitrag "Re: Browsercache ausschalten"
[6] https://developer.mozilla.org/de/docs/Web/HTTP/Guides/Caching
Hallo Ernst und Ein T.,
vielen Dank für die interessanten Ausführungen! Verstehe ich das
richtig, das File-Format und der Inhalt haben keinen Einfluss auf das
Caching, auch mit dem Text-File kann ich das machen, wenn nur der
File-Server den HTTP-Header
Ein T. schrieb:
> "Expires" auf "0"
setzt oder
Εrnst B. schrieb:
> "Cache-Control: no-cache"
Dann muss ich dem Server nur noch Header beibringen!
Gruss Chregu
Christian M. schrieb:
> vielen Dank für die interessanten Ausführungen! Verstehe ich das
> richtig, das File-Format und der Inhalt haben keinen Einfluss auf das
> Caching, [...]
Korrekt, der "Content-Type" hat keinen Einfluß auf das Caching.
Die ganzen Cache-Header verstehen die Browser nur als Empfehlung. Oft
cachen sie trotzen für eine gewisse minimale Zeit. Die Zufallszahlen in
den URLs sind nach meinem Kenntnisstand die beste Lösung.
Sherlock 🕵🏽♂️ schrieb:
> Die ganzen Cache-Header verstehen die Browser nur als Empfehlung. Oft
> cachen sie trotzen für eine gewisse minimale Zeit. Die Zufallszahlen in
> den URLs sind nach meinem Kenntnisstand die beste Lösung.
Wenn ich RFC 9111, Absätze 3 und 5 (sowie die RFCs 2119 und 8174)
richtig verstehe, würden sich diese Browser nicht RFC-konform verhalten,
wenn sie einen Header wie "Cache-Control" oder "Expires" ignorieren
würden:
"A cache MUST NOT store a response to a request unless:
* the no-store cache directive is not present in the response
* the response contains at least one of the following:
- an Expires header field" (RFC 9111, §3, [1])
Zumindest bei den verbreiteteren Browsern würde ich mich sehr wundern,
wenn die so ein wichtiges Feature nicht korrekt implementiert hätten.
Aber klar, der Teufel ist bekanntlich ein Eichhörnchen. :-)
[1]
https://datatracker.ietf.org/doc/html/rfc9111#name-storing-responses-in-caches
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|