it-swarm.com.de

Stoppen Sie den Browser, um HTTP-Anforderungen für Bilder zu senden, die zwischengespeichert bleiben sollen - mod_expires

Nachdem ich viele Artikel und einige Fragen hier gelesen hatte, konnte ich endlich den Apache mod_expires aktivieren, um dem Browser mitzuteilen, dass er Bilder für 1 Jahr zwischenspeichern MUSS .

<filesMatch "\.(ico|gif|jpg|png)$">
  ExpiresActive On
  ExpiresDefault "access plus 1 year"
  Header append Cache-Control "public"
</filesMatch>

Und zum Glück scheinen die Serverantworten korrekt zu sein:

HTTP/1.1 200 OK 
Date: Fri, 06 Apr 2012 19:25:30 GMT 
Server: Apache 
Last-Modified: Tue, 26 Jul 2011 18:50:14 GMT 
Accept-Ranges: bytes 
Content-Length: 24884 
Cache-Control: max-age=31536000, public 
Expires: Sat, 06 Apr 2013 19:25:30 GMT
Connection: close
Content-Type: image/jpeg 

Nun, ich dachte, dies würde den Browser stoppen und den Server für 1 Jahr nach den Bildern fragen. Aber es ist teilweise wahr: Ursache Wenn Sie den Browser schließen und erneut öffnen, lädt der Browser die Bilder NICHT mehr herunter vom Server, aber der Browser fragt den Server immer noch mit einer HTTP-Anfrage für jedes Bild an .

Wie erzwinge ich, dass der Browser keine HTTP-Anforderungen für jedes Bild mehr erstellt? Auch wenn auf diese HTTP-Anforderungen kein Bild heruntergeladen wird, handelt es sich dennoch um Anforderungen an den Server die die Latenz unnötig erhöhen und das Rendern der Seite verlangsamen!

Ich habe dem Browser bereits gesagt, dass er die Bilder 1 Jahr im Cache behalten MUSS! Warum fragt der Browser den Server immer noch nach jedem Bild ab (auch wenn das Bild nicht heruntergeladen wird) ?!


Wenn ich mir die Netzwerkgraphen in FireBug anschaue (Menü FireBug> Net> Images), kann ich verschiedene Caching-Verhalten feststellen.

  • Wenn die Seite zum ersten Mal geladen wird, werden alle Bilder heruntergeladen (und dasselbe passiert, wenn ich ein Seiten-Reload erzwinge, indem ich auf die Schaltfläche "Seite neu laden" des Browsers klicke). Das macht Sinn!

  • Wenn ich auf der Website navigiere und zur gleichen Seite zurückkehre werden die Bilder überhaupt nicht heruntergeladen und der Browser fragt NICHT einmal den Server an nach einem der Bilder. Das macht Sinn, und ich möchte dieses Verhalten auch sehen, wenn der Browser geschlossen ist)!

  • Wenn ich den Browser schließe und ihn auf derselben Seite wieder öffne, sendet der alberne Browser trotzdem einmal pro Bild eine HTTP-Anfrage an den Server: Das Bild wird NICHT downalodiert, aber es wird immer noch eine HTTP-Anfrage gesendet Browser fragt den Server nach dem Bild (Server antwortet mit 200 OK). Das ist derjenige, der mich irritiert!

Bei Interesse füge ich auch die folgenden Grafiken bei:

enter image description here

enter image description here

BEARBEITEN: Ich habe es jetzt auch mit FireFox 11.0 getestet, um sicherzugehen, dass mein FireFox 3.6 nicht zu alt ist. Das gleiche passiert !!! Ich habe auch Google-Site und Stackoverflow-Site getestet , beide senden den Cache-Control: max-age=..., aber der Browser sendet weiterhin eine HTTP-Anfrage für jedes Bild an den Server, sobald der Browser auf derselben Seite geschlossen und wieder geöffnet wird , nach der Server-Antwort lädt der Browser das Bild NICHT herunter (wie oben erklärt), aber er stellt trotzdem die verdammte Anfrage, die die Zeit zum Anzeigen der Seite erhöht.

EDIT2: Das Entfernen des Last-Modified-Headers wie vorgeschlagen hier löst das Problem nicht, es macht keinen Unterschied.

44
Marco Demaio

Sie haben das falsche Werkzeug zur Analyse der Anfragen verwendet.

Ich würde das wirklich nützliche Firefox-Addon Live HTTP-Header empfehlen, damit Sie sehen können, was wirklich im Netzwerk vorgeht.

Und um sicherzugehen, können Sie Ihren Server ssh/PuTTY und so etwas tun 

tail -f /var/log/Apache2/access.log
14
Oliver Kurmis

Das Verhalten, das Sie sehen, ist das beabsichtigte (siehe RFC7234 für weitere Details), angegebenes Verhalten: 

Alle modernen Browser senden unabhängig vom Cache-Status für jedes angezeigte Seitenelement HTTP-Anforderungen an den Server. Dies war eine Entwurfsentscheidung, die auf Anfrage von Web-Services (insbesondere Werbenetzwerken) getroffen wurde, um sicherzustellen, dass HTTP-Server in der Lage sind, Aufzeichnungen zu jeder Anzeige jedes Elements zu führen. 

Wenn die Browser diese Anforderungen nicht gestellt haben, wird der Server niemals darüber informiert, dass dem Benutzer ein Bild angezeigt wurde. Für Werbenetzwerke wäre dies katastrophal. Früher hackten sich Werbenetzwerke durch das gleiche Image mit zufällig generierten Namen (z. B. 'coke_ad_1_98719283719283.gif') durch. Für ISPs verursachte diese Praxis jedoch einen erheblichen Anstieg der Datenübertragungen, da jeder ihrer Benutzer diese identischen Anzeigenbilder erneut herunterlud und dabei alle Zwischenspeicher-/Proxy-Server ihres ISPs umging.

So wurde ein Waffenstillstand erreicht: Browser würden immer HTTP-Anforderungen senden, selbst für nicht abgelaufene zwischengespeicherte Elemente. Server würden mit HTTP 304-Statuscodes antworten ("nicht geändert"). Dadurch können die Server die Tatsache aufzeichnen, dass das Image dem Client angezeigt wurde. Aus diesem Grund haben Werbe-Netzwerke generell aufgehört, randomisierte Bildnamen zu verwenden, um Netzwerk-Cache-Server zu umgehen.

Dies gab den Werbenetzwerken das, was sie wollten - eine Aufzeichnung jedes angezeigten Bildes - und es gab den ISPs, was sie wollten - Cache-fähige Bilder und statischen Inhalt.

Aus diesem Grund können Sie nicht viel tun, um zu verhindern, dass Browser HTTP-Anforderungen für zwischengespeicherte Seitenelemente senden.

Wenn Sie jedoch andere verfügbare clientseitige Lösungen betrachten, die mit html5 mitgeliefert wurden, besteht ein Spielraum, um das Laden von Ressourcen zu verhindern

  1. Cache Manifest (trotz der gotchas)
  2. IndexedDB (Nette asynchrone Funktionen, ermöglicht Blob-Speicherung)
  3. Lokaler Speicher (nicht asynchron)
27
Jason Buberel

Es gibt einen Unterschied zwischen "Nachladen" und "Aktualisieren". Durch das Navigieren zu einer Seite mit den Schaltflächen "Zurück" und "Vorwärts" werden normalerweise keine neuen HTTP-Anforderungen initiiert. Wenn Sie jedoch die Taste F5 drücken, um die Seite zu "aktualisieren", wird der Cache des Browsers überprüft. Dies ist vom Browser abhängig, scheint aber für FF und Chrome die Norm zu sein (dh die Browser, die den Netzwerkverkehr problemlos überwachen können.) Wenn Sie F6 drücken, drücken Sie die Eingabetaste, um die URL-Adressleiste zu fokussieren und dann darauf zu "gehen" Laden Sie die Seite neu, überprüfen Sie jedoch nicht die Assets auf der Seite.

Update: Verdeutlichung des Vorwärts- und Rückwärtsnavigationsverhaltens. In Browsern heißt es "Back Forward Cache" oder BFCache. Wenn Sie mit den Schaltflächen "Zurück" und "Vorwärts" navigieren, besteht die Absicht, Ihnen genau so anzuzeigen, wie Sie sie in Ihrer eigenen Zeitleiste gesehen haben. Es werden keine Serveranforderungen bei der Verwendung von "Zurück" und "Vorwärts" ausgeführt, auch wenn ein Server-Cache-Header angibt, dass ein bestimmtes Element abgelaufen ist.

Wenn in Ihrem Entwickler-Netzwerkfenster (200 OK BFCache) angezeigt wird, wurde der Server nie getroffen, selbst wenn Sie gefragt wurden, ob -modified-since.

http://www.softwareishard.com/blog/firebug/firebug-tip-what-the-heck-is-bfcache/

11
chugadie

Wenn ich eine Aktualisierung mit F5 oder F5 + Ctrl erzwinge, wird eine Anfrage gesendet. Wenn ich jedoch den Browser schließe und die URL erneut eingeben, wird KEIN Bedarf gesendet. Die Art und Weise, wie ich getestet habe, ob eine Anforderung gesendet wurde oder nicht, bestand darin, Haltepunkte bei der Startanforderung auf dem Server zu verwenden, auch wenn eine Anforderung nicht gesendet wird. In Firebug wird jedoch immer noch eine Wartezeit von 7 ms angezeigt. Beachten Sie dies.

7
Peter Lundsby

Was Sie hier beschreiben, spiegelt nicht meine Erfahrung wider. Wenn Inhalte mit einer No-Store-Direktive bereitgestellt werden oder Sie eine explizite Aktualisierung durchführen, ist dies der Fall, wenn Sie zum Origin-Server zurückkehren. Andernfalls sollte der Browser zwischen Browser-Neustarts zwischengespeichert werden (vorausgesetzt, dies ist zulässig und kann schreiben.) eine Cache-Datei).

Wenn Sie Ihre Wasserfälle etwas detaillierter betrachten (was schwierig ist, weil sie etwas klein und verschwommen sind), scheint der Browser genau das zu tun, was er tun sollte - es sind hat -Einträge für die Bilder -, aber diese sind nur aus dem lokalen Cache nicht vom Origin-Server laden - Überprüfen Sie den 'Date' -Header in der Antwort (Warum dauert es Ihrer Meinung nach Millisekunden statt Sekunden?). Deshalb sind sie anders gefärbt.

6
symcbean

Nachdem ich viel Zeit auf der Suche nach einer vernünftigen Antwort verbracht hatte, fand ich den folgenden Link am nützlichsten und er beantwortet die hier gestellte Frage.

https://webmasters.stackexchange.com/questions/25342/headers-to-prevent-304-if-modified-since-head-requests

4
dev-vb

Was Sie in Chrome sehen, ist keine Aufzeichnung der tatsächlichen HTTP-Anforderungen - es ist eine Aufzeichnung der Asset-Anforderungen. Chrome zeigt dies an, um anzuzeigen, dass ein Asset tatsächlich von der Seite angefordert wird. Diese Ansicht zeigt jedoch nicht wirklich an, ob die Anforderung erfolgt. Wenn ein Asset zwischengespeichert wird, erstellt Chrome niemals die zugrunde liegende HTTP-Anforderung.

Sie können dies auch überprüfen, indem Sie den Mauszeiger über die violetten Segmente in der Timeline bewegen. Zwischengespeicherte Ressourcen haben einen (from cache) in der QuickInfo.

Um die tatsächlichen HTTP-Anforderungen zu sehen, müssen Sie auf einer niedrigeren Ebene suchen. In einigen Browsern kann dies mit einem Plugin (wie Live HTTP Headers) erfolgen.

Um jedoch zu überprüfen, dass die Anforderungen nicht tatsächlich gestellt werden, müssen Sie Ihre Serverprotokolle überprüfen oder einen Debugging-Proxy wie Charles oder Fiddler verwenden. Dies funktioniert auf HTTP-Ebene, um sicherzustellen, dass die Anforderungen nicht tatsächlich ausgeführt werden.

0
wharding28

Diese Frage hat eine bessere Antwort hier bei Webmaster-Stack-Exchange-Site.

Weitere Informationen, die auch im obigen Link zitiert werden, finden Sie unter httpwatch

Nach dem Artikel:

Es gibt eine Reihe von Situationen, in denen Internet Explorer überprüfen muss, ob ein zwischengespeicherter Eintrag gültig ist:

  • Der zwischengespeicherte Eintrag hat kein Ablaufdatum und der Inhalt wird zum ersten Mal in einer Browsersitzung aufgerufen
  • Der zwischengespeicherte Eintrag hat ein Ablaufdatum, aber er ist abgelaufen
  • Der Benutzer hat eine Seitenaktualisierung angefordert, indem er auf die Schaltfläche Aktualisieren klickt oder F5 drückt

    code hier eingeben

0

Cache-Validierung und die Antwort 304

Es gibt eine Reihe von Situationen, in denen Internet Explorer überprüfen muss, ob ein zwischengespeicherter Eintrag gültig ist:

  • Der zwischengespeicherte Eintrag hat kein Ablaufdatum und der Inhalt wird zum ersten Mal in einer Browsersitzung aufgerufen

  • Der zwischengespeicherte Eintrag hat ein Ablaufdatum, aber er ist abgelaufen

  • Der Benutzer hat eine Seitenaktualisierung angefordert, indem er auf die Schaltfläche Aktualisieren klickt oder F5 drückt

Wenn der zwischengespeicherte Eintrag ein Datum der letzten Änderung hat, sendet IE es im Header If-Modified-Since einer GET-Anforderungsnachricht:

GET /images/logo.gif HTTP/1.1
Accept: */*
Referer: http://www.google.com/
Accept-Encoding: gzip, deflate
If-Modified-Since: Thu, 23 Sep 2004 17:42:04 GMT
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)
Host: www.google.com

Der Server überprüft den If-Modified-Since-Header und antwortet entsprechend. Wenn der Inhalt seit dem angegebenen Datum nicht geändert wurde, antwortet er mit dem Statuscode 304 und einer Antwortnachricht, die nur Kopfzeilen enthält:

HTTP/1.1 304 Not Modified
Content-Type: text/html
Server: GWS/2.1
Content-Length: 0
Date: Thu, 04 Oct 2004 12:00:00 GMT

Die Antwort kann schnell heruntergeladen werden, da sie keinen Inhalt enthält und IE veranlasst, die erforderlichen Daten aus dem Cache zu lesen. Im Grunde ist es eine Umleitung in den Cache des lokalen Browsers.

Wenn sich das angeforderte Objekt seit dem Datum/der Uhrzeit im Header If-Modified-Since tatsächlich geändert hat, antwortet der Server mit dem Statuscode 200 und liefert die geänderte Version der Ressource.

0
Rakesh

Wenn es um Leben oder Tod geht (Wenn Sie das Laden von Seiten auf diese Weise optimieren möchten oder wenn Sie die Serverlast auf jeden Fall so weit wie möglich reduzieren möchten), dann gibt es IS eine Problemumgehung .

Verwenden Sie HTML5 local storage, um Bilder zu zwischenspeichern, nachdem sie zum ersten Mal angefordert wurden.

  • [+] Sie können den Browser daran hindern, HTTP-Anforderungen zu senden. Diese würden in 99% 304 (nicht geändert) zurückgeben, unabhängig davon, wie sehr der Benutzer versucht (F5, Strg + F5, nur die Seite erneut aufrufen usw.)

  • [-] Dazu müssen Sie die Javascript-Unterstützung zusätzlich einsetzen.

  • [-] Bilder werden in base64 gespeichert (wir können keine binären Daten speichern), weshalb sie auf Clientseite jedes Mal dekodiert werden. Das ist normalerweise ziemlich schnell und keine große Sache, aber es ist immer noch etwas zusätzliche CPU-Auslastung auf der Clientseite und sollte im Auge behalten werden.

  • [-] Der lokale Speicher ist begrenzt. Sie können etwa 5 MB Daten pro Domäne verwenden (Hinweis: base64 fügt der Originalgröße des Bildes ~ 30% hinzu).

  • [?] Unterstützt von Mehrheit der Browser. http://caniuse.com/#search=localstorage

Beispiel

Prüfung

0
djeendo