Warum browser nicht senden "If-None-Match" - header?
Ich versuche zu downloaden (und hoffentlich cache) ein dynamisch geladenes Bild in PHP. Hier sind die Header gesendet und empfangen werden:
Anfrage:
GET /url:resource/Pomegranate/resources/images/logo.png HTTP/1.1
Host: pome.local
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: PHPSESSID=fb8ghv9ti6v5s3ekkmvtacr9u5
Antwort:
HTTP/1.1 200 OK
Date: Tue, 09 Apr 2013 11:00:36 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.14 ZendServer/5.0
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Disposition: inline; filename="logo"
ETag: "1355829295"
Last-Modified: Tue, 18 Dec 2012 14:44:55 Asia/Tehran
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: image/png
Wenn ich die URL neu laden, die genau die gleiche Header gesendet und empfangen werden. Meine Frage ist, was soll ich senden in meiner Antwort zu sehen, die If-None-Match
- header in der konsequenten Anfrage?
HINWEIS: ich glaube, dass diese Header wurden gut lange nicht gemeldet, obwohl ich nicht sicher sein kann, aber ich denke, Browser geändert, nicht zum senden der If-None-Match
header mehr (ich verwendet, um zu sehen, dass der header). Ich Teste mit Chrome und Firefox und beide scheitern zu senden der header.
Last-Modified: Tue, 18 Dec 2012 …
undExpires: Thu, 19 Nov 1981 08:52:00 GMT
widersprechen einander ein wenig, meinst du nicht?- Das ist, weil ich will, um sicherzustellen, dass es nicht im Cache im browser. Ich habe nur die
Expires
gleichLast-Modified
und bekam das gleiche Ergebnis. - Am Anfang Ihrer Frage, die Sie sagen, Sie wollen Zwischenspeichern, und jetzt müssen Sie nicht?
- Ich versuche, die Implementierung eines reverse-proxy-cache-system, für die, die ich brauche, um sicherzustellen, dass browser nicht den cache alles lokal. Stattdessen sollte es Fragen web server für Ressourcen, die man jedes mal braucht Sie während der Präsentation die version der aktuellen Kopie (falls vorhanden). Browser senden soll Ressourcen " aktuelle version durch ` aber es funktioniert nicht. Die Ergebnisse in herunterladen der Ressourcen zu jeder Zeit. Aber wenn der browser gelingt es, geschickt die Ressourcen-version, PHP sagen kann, wenn es nötig ist, aktualisieren Sie die Ressource, sonst wird es zu senden "304" - header, die dem browser mitteilt, seine zwischengespeicherte version.
- Sorry, aber es sieht für mich so aus als ob Sie gerade mischen jede Art von Kopf Sie denken können, ohne jede Logik. Sie sagen
Cache-Control: no-store, no-cache
– erwarten aber, dass die Zwischenspeicherung geschehen? - Vielleicht haben Sie Recht. Nun, ich denke, diejenigen, die
Cache-Control
Header sollte das problem verursachen. Die Sache ist, dass ich nicht senden Sie. Sie müssen automatisch generiert werden. lassen Sie mich sehen, wenn ich kann verhindern, dass Sie gesendet wird. - Vielen Dank, es hat funktioniert. Würden Sie bitte die Ehre zu senden, die als Antwort (nur fürs Protokoll)?
- Das ist echt doof, aber ich habe gerade 4 Stunden an der Umsetzung dieser mit Hilfe von verschiedenen Methoden in meiner .NET Web Api, nur um zu erkennen, mein chrome dev tools-caching deaktiviert. Stellen Sie sicher, dass Sie dies ausschalten, zum testen dieses in Chrom!!!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Deine Antwort-Header enthalten
Cache-Control: no-store, no-cache
; diese verhindern, dass caching.Entfernen Sie diese Werte (ich denke
must-revalidate, post-check=0, pre-check=0
könnte/sollte gehalten werden – Sie sagen, der browser mit dem server, wenn es eine änderung gab).Und ich würde stick mit
Last-Modified
allein (wenn die änderungen an Ihren Ressourcen können erkannt werden mit diesem Kriterium allein) –ETag
ist etwas kompliziert zu handhaben (vor allem, wenn Sie sich mit ihm in Ihrem PHP-Skript selbst), und Google PageSpeed/YSlow abraten, eine zu.Cache-Control
header wurde automatisch generiert, ohne von mir zu wissen. Ich verwendet PHP ' s header_remove stoppen Sie alle unerwünschten Header, bevor ich senden meine eigenen. Vielen Dank.Gleiche Problem, Ähnliche Lösung
Ich habe versucht zu ermitteln, warum Google Chrome nicht senden
If-None-Match
Header beim Besuch einer Seite, die ich entwickle. (Chrome 46.0.2490.71 m, obwohl ich nicht sicher bin, wie aktuell die version ist.)Dies ist ein anderes — wenn auch sehr ähnlichen — Antwort als die OP letztlich zitiert (in einem Kommentar in Bezug auf die Akzeptierte Antwort), aber er behandelt das gleiche problem:
Den browser sendet nicht die
If-None-Match
- header, die in nachfolgenden Anfragen", wenn Sie es sollen" (D. H., server-side Logik, über PHP oder ähnliches, wurde verwendet, um eineETag
oderLast-Modified
- header in der ersten Antwort).Voraussetzungen
Unter Verwendung eines selbst-signierten TLS-Zertifikat, das sich der lock rot in Chrom, änderungen von Chrome caching-Verhalten. Bevor Sie versuchen, ein Problem zu beheben dieser Art, installieren Sie das selbstsignierte Zertifikat in den effektiven Speicher für Vertrauenswürdige Stammzertifizierungsstellen, und komplett den browser neu starten, wie Eingangs ausgeführt,https://stackoverflow.com/a/19102293 .
1. Epiphanias: If-None-Match erfordert eine ETag von der server zuerst
Erkannte ich Recht schnell, dass Chrome (und wohl den meisten oder allen anderen Browsern) nicht senden Sie eine
If-None-Match
Kopfzeile, bis die server schon gesendet eineETag
header in der Antwort auf eine frühere Anfrage. Logisch, das macht Sinn; schließlich, wie könnte Chrome sendenIf-None-Match
wenn es nie das Wert?Diese führen mich auf meinem server-seitige Logik — vor allem, wie die Header werden gesendet, wenn ich will, dass die user-agent-cache, um die Antwort—, in einer Anstrengung, um festzustellen, aus welchem Grund die
ETag
- header nicht gesendet wird, in Reaktion auf Chrome die erste Anfrage für die Ressource. Ich hatte berechnet Anstrengungen Unternehmen wird, um dieETag
header in meinem Anwendungslogik.Habe ich gerade mit PHP, also @Mehran 's (OP' s), Kommentar, sprang an mir (er/Sie sagt, dass der Aufruf
header_remove()
vor dem senden die gewünschte cache-bezogene Header löst das problem).Ehrlich, ich war skeptisch über diese Lösung, denn a) war ich mir ziemlich sicher, dass PHP nicht senden würde alle Header, der seine eigene standardmäßig (und es nicht, da meine Konfiguration); und b) wenn ich rief
var_dump(headers_list());
kurz vor meinem custom-caching-Header in PHP, die nur header setzen, war ein, dass ich die Einstellung wurde absichtlich gerade vor:So, hat auch nichts zu verlieren, ich habe versucht, den Aufruf
header_remove();
nur vor dem senden meine custom-Header. Und viel zu meiner überraschung, PHP, begann das senden derETag
header plötzlich!2. Epiphany: Gzip die Resonanz ändert seinen hash
Es dann mich, traf mich wie ein Sack Steine: durch die Angabe der
Content-type
- header in PHP, sagte ich zu NGINX (webserver verwende ich) GZIP die Antwort, wenn PHP Händen es zurück zu den NGINX! Klar zu sein, dasContent-type
dass ich die Angabe wurde auf NGINX Liste der Arten gzip.Für Gründlichkeit, meine NGINX GZIP-Einstellungen sind wie folgt, und PHP-Kabel-bis zu NGINX via php-fpm:
Dachte ich darüber nach, warum NGINX entfernen könnten die
ETag
, die ich gesandt hatte, in PHP, wenn eine "gzippable" content-type angegeben wird, und kam mit einer jetzt-offensichtliche Antwort: weil NGINX ändert die Antwort Körper, PHP geht zurück, wenn NGINX Gzip-Dateien es! Das macht auch Sinn; es gibt keinen Punkt in senden Sie denETag
wenn es nicht überein die Antworten zu generieren. Es ist ziemlich glatt, die NGINX verarbeitet dieses Szenario so intelligent.Ich weiß nicht, ob NGINX schon immer klug genug, um nicht zu komprimieren Antwort-Gremien, unkomprimierte aber enthalten
ETag
Header, aber das scheint das zu sein, was hier passiert.UPDATE: ich fand Kommentar, der erklärt, NGINX ' s Verhalten in dieser Hinsicht, die wiederum zitiert zwei wertvolle Diskussionen zu diesem Thema:
Posted on Jun 15, 2013 by Massive Bird
.Im Interesse der Erhaltung dieser wertvollen Erklärung, sollte es passieren, um zu verschwinden, ich zitiere aus
Massive Bird
's Beitrag zu der Diskussion:Jedoch, NGINX ' s Verhalten in dieser Hinsicht könnte erwogen werden leicht fehlerhaft, dass die gleiche Spezifikation
Ich bin mir nicht sicher, da NGINX die aktuelle disposition in dieser Hinsicht, und speziell, ob oder nicht es hat Unterstützung für "schwache" Etags.
Also, Was ist die Lösung?
Also, was ist die Lösung zu bekommen
ETag
in die Antwort? Tun die Gzip in PHP, so dass NGINX sieht, dass die Antwort bereits komprimiert, und einfach geht es entlang, während er dasETag
header intakt:Sobald ich dazu rufen Sie vor dem senden der Header und der response-body, PHP, begann das senden der
ETag
Wert mit jeder Antwort. Ja!Andere Lektionen Gelernt
Hier sind einige interessante Leckerbissen, die er aus meiner Forschung. Diese information ist besonders praktisch, wenn Sie versuchen zu testen, ein server-side-caching-Implementierung, ob in PHP oder einer anderen Sprache.
Chrome, und seine Entwickler-Tools "Net" - panel, Verhalten sich anders, je nachdem, wie die Anfrage initiiert.
Wenn die Anforderung ist "frisch hergestellt", z.B., durch drücken
Ctrl+F5
, Chrome sendet diesen Header:und der server antwortet
200 OK
.Wenn der Antrag mit nur
F5
, Chrome sendet diesen Header:und der server antwortet
304 Not Modified
.Schließlich, wenn die Anforderung erfolgt durch einen Klick auf einen link, um die Seite Sie sind bereits Leser, oder Platzierung Schwerpunkt in der Chrome-Adressleiste und drücken Sie die EINGABETASTE, Chrome sendet diesen Header:
und der server antwortet
200 OK (from cache)
.Während dieses Verhalten zunächst ein wenig verwirrend, wenn Sie nicht wissen, wie es funktioniert, ist es ideal Verhalten, denn er erlaubt es, testen Sie jede mögliche Anfrage/Antwort-Szenario sehr gründlich.
Vielleicht die meisten verwirrend ist, dass Chrome fügt automatisch die
Cache-Control: no-cache
undPragma: no-cache
Header in der ausgehenden Anforderung , wenn in der Tat Chrome ist der Erwerb, die Antworten aus seinem cache (wie man an der200 OK (from cache)
Antwort).Diese Erfahrung war eher informativ für mich, und ich hoffe, andere finden in dieser Analyse der Wert in der Zukunft.
Cache-Control: no-cache
header, und schließlich das problem gefunden ist, der kleine checkbox.... seufzDieses Posting für die Zukunft mir...
Ich hatte ein ähnliches problem, ich war senden
ETag
in der Antwort, aber der HTTP-client nicht sendenIf-None-Match
header in der nachfolgenden Anforderungen (was seltsam war, denn es war der Tag vor).Stellt sich heraus, ich war mit
http://localhost:9000
für die Entwicklung (nicht VerwendungIf-None-Match
) - durch die Umstellung aufhttp://127.0.0.1:9000
Chrome1 automatisch gestartet, das senden derIf-None-Match
header in den Anfragen wieder.Zusätzlich sorgen
Devtools > Network > Disable Cache [ ]
deaktiviert ist.Chrome: Version 71.0.3578.98 (Offizieller Build) (64-bit)
1, die ich nirgendwo finden kann, dies ist dokumentiert - ich gehe davon aus Chrom war verantwortlich für diese Logik.
Passiert mir wegen 2 Gründen:
Mein server nicht senden etag response-header. Ich aktualisierte mein jetty web.xml zurück etag, indem Sie den folgenden:
URL ich aufgerufen wurde für die xml-Datei. Wenn ich es geändert auf html-Datei, chrome-Start senden "if-none-match" - header!
Ich hoffe, es hilft jemand
Ähnliches problem
Ich war versuchen, erhalten Sie eine Bedingte GET-Anfrage mit
If-None-Match
header, die Lieferung der richtigenEtag
header, aber ohne Erfolg in jedem browser den ich ausprobiert habe.Nach einer Menge von Versuch ich merke, dass der Browser behandeln beide
GET
undPOST
auf den gleichen Pfad wie eine gleiche cache-Kandidat. Damit haben dieGET
mit der richtigenEtag
wurde wirksam gekündigt mit sofortiger "POST" auf den gleichen Pfad mitCache-Control:"no-cache, private"
, obwohl es geliefert wurdeX-Requested-With:"XMLHttpRequest"
.Hoffe, dass dies hilfreich sein, um jemanden.
Dies geschah zu mir, denn ich hatte die cache-Größe zu klein ist (über die Gruppenrichtlinien).
Es geschah nicht im Incognito, das ist, was machte mir klar, dies könnte der Fall sein.
Festsetzung, dass das Problem behoben werden.