So verhindern Sie den Browser-Cache für PHP-Sites

120

Ich habe eine PHP-Site in Cloud-Server ausgeführt. Wenn ich neue Dateien CSS, JS oder Bilder hinzufüge, lädt der Browser die gleichen alten JS-, CSS- und Bilddateien, die im Cache gespeichert sind.

Meine Website hat einen Doctype und ein Meta-Tag wie unten

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta http-equiv="Page-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Page-Exit" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Exit" content="blendTrans(Duration=1.0)">

Aufgrund des obigen Doctype und Metacodes lade ich die gleichen Dateien, die im Browser zwischengespeichert sind, anstatt der neuen

ArrayOutOfBound
quelle
No Cache in all Browsers. Sie können auch eine? RandomGeneratedNumber für die Dateien erstellen, die nicht zwischengespeichert werden sollen.
Kodemon
2
Sie möchten den Cache wahrscheinlich nicht vollständig für images / js / css deaktivieren: stackoverflow.com/questions/4206224/…
FoolishSeth
Widerstand der Versuchung zu Nekro, aber bitte, jeder, der dies in Betracht zieht: Hör auf. Lernen Sie, das Caching zu steuern und zu verwenden. Deaktivieren Sie es nicht einfach blind aufgrund einer unangenehmen Episode. Lesen Sie das Kapitel über das Zwischenspeichern von HTTP. Das endgültige Handbuch - Dieses Buch (und die RFCs) sollten mit einem Test obligatorisch gelesen werden. Erfahren Sie, wie Sie den zuletzt geänderten Wert angeben, auf If-Modified-Since reagieren und die ETag-Identifikation verwenden. Wenn das Asset aktualisiert wird, werden die Browser informiert, wenn aus diesem 304 wieder ein 200 wird.
Amcgregor

Antworten:

282

Versuche dies

<?php

header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>
Codesen
quelle
6
Mit Ausnahme von "max-age = 0" sind dies die Header, die von PHP gesendet wurden, ohne die obigen Angaben in meiner Installation anzugeben. Es scheint, dass PHP standardmäßig versucht, das Zwischenspeichern von Browsern zu verhindern ...
schnelle Reflexe
1
Ich habe ein WordPress-Plugin, das ein alternatives Thema an alte Versionen von Internet Explorer sendet, und es wurde auf einigen Caching-Systemen schlecht ausgelöst. Dieser Beitrag wurde bei meiner ersten Google-Suche veröffentlicht. Gut gespielt.
Imperativ
3
Denken Sie daran, dass dies nicht in HTML eingebettet werden kann. Dies sollte ganz oben auf der Seite sein.
Hunter S
9
Hinweis: Wenn Sie es session_start()später verwenden, wird Ihr Header überschrieben, Cache-Control: private, max-age=10800, pre-check=10800da der Standardwert von 180 Minuten ist session.cache_expire. Wenn Sie das Starten der Sitzung nicht vermeiden können, aber die Cache-Verwendung deaktivieren müssen session_cache_limiter('private');session_cache_expire(0);.
mgutt
2
@thdoan Der zweite Parameter der headerFunktion ist ein Boolescher Wert zum Ersetzen . Der optionale Ersetzungsparameter gibt an, ob der Header einen vorherigen ähnlichen Header ersetzen oder einen zweiten Header desselben Typs hinzufügen soll.
MrReiha
36

Hier, wenn Sie es über HTML steuern möchten: Gehen Sie wie folgt vor folgt vor: Option 1:

<meta http-equiv="expires" content="Sun, 01 Jan 2014 00:00:00 GMT"/>
<meta http-equiv="pragma" content="no-cache" />

Und wenn Sie es über PHP steuern möchten: Gehen Sie wie folgt vor folgt vor: Option 2:

header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');

UND Option 2 IST IMMER BESSER, um Probleme mit dem Proxy-basierten Caching zu vermeiden.

Ritesh Aryal
quelle
10

Sie können dies versuchen:

    header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
    header("Connection: close");

Hoffentlich hilft es, Cache zu verhindern, wenn überhaupt!

Aakanksha
quelle
Dies betrifft nur das Caching der HTML-Dateien, oder? Und hat nichts mit eTag zu tun? Vielen Dank!
Sam Levin
4
Nur die erste Zeile sollte vollkommen ausreichen. Die fünfte Zeile ist eindeutig falsch und hat nichts mit einer Serverantwort zu tun (es handelt sich um einen Anforderungsheader). Die sechste Zeile hat jedoch keinerlei Auswirkungen. Ich könnte weitermachen ...
The Surrican
Der Ansatz der Schrotflinte: Alles an die Wand werfen, hoffen, dass etwas klebt. Gemäß meinem Kommentar zur Frage selbst kann ich dringend empfehlen, sich eine Kopie von HTTP: The Definitive Guide zu schnappen und das Kapitel über Caching zu lesen. Auch die RFCs, aber diese zu lesen, ist eine besondere Fähigkeit. ("Connection: close" ist ein lustiger Foot-Shot, der das effiziente Pipelining von Anforderungen deaktiviert oder nichts
unternimmt
7

Ich hatte Probleme beim Zwischenspeichern meiner CSS-Dateien. Das Festlegen von Headern in PHP hat mir nicht geholfen (möglicherweise, weil die Header in der Stylesheet-Datei anstelle der damit verknüpften Seite festgelegt werden müssten?).

Ich habe die Lösung auf dieser Seite gefunden: https://css-tricks.com/can-we-prevent-css-caching/

Die Lösung:

Fügen Sie den Zeitstempel als Abfrageteil des URI für die verknüpfte Datei hinzu.
(Kann für CSS, JS, Bilder usw. verwendet werden.)

Zur Entwicklung:

<link rel="stylesheet" href="style.css?<?php echo date('Y-m-d_H:i:s'); ?>">

Für die Produktion (wo Caching meistens eine gute Sache ist):

<link rel="stylesheet" type="text/css" href="style.css?version=3.2">
(und manuell umschreiben, wenn es erforderlich ist)

Oder eine Kombination dieser beiden:

<?php
    define( "DEBUGGING", true ); // or false in production enviroment
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo (DEBUGGING) ? date('_Y-m-d_H:i:s') : ""; ?>">

BEARBEITEN:

Oder eine schönere Kombination dieser beiden:

<?php
    // Init
    define( "DEBUGGING", true ); // or false in production enviroment
    // Functions
    function get_cache_prevent_string( $always = false ) {
        return (DEBUGGING || $always) ? date('_Y-m-d_H:i:s') : "";
    }
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo get_cache_prevent_string(); ?>">
Lukas
quelle
Beliebige Versionen, aktuelle Zeitstempel (Caching vollständig besiegen)… aber nicht das, was tatsächlich Sinn macht und funktioniert, unabhängig davon, ob ein "Debugging" -Flag vorliegt oder nicht. Warum verwenden Sie nicht die tatsächliche Zeit der Datei? Dann müssten Sie das PHP buchstäblich nie aktualisieren, und Caches würden nicht vollständig und fantastisch nutzlos. Oder liefern Sie Ihre Statik einfach mit einem ordnungsgemäß konfigurierten HTTP-Server wie Nginx oder Apache, der einen geeigneten Last-Modified- und ETag-Server festlegt. In ähnlicher Weise existiert diese Art von "Debugging" -Flag bereits ... im Browser. (Caches
deaktivieren
5

Das Verhindern des Browser-Cache ist je nach Fall keine gute Idee. Auf der Suche nach einer Lösung habe ich Lösungen wie diese gefunden:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=filemtime($file);?>">

Das Problem hierbei ist, dass, wenn die Datei während eines Updates auf dem Server überschrieben wird, was mein Szenario ist, der Cache ignoriert wird, da der Zeitstempel geändert wird, auch wenn der Inhalt der Datei derselbe ist.

Ich verwende diese Lösung, um den Browser zu zwingen, Assets nur herunterzuladen, wenn sein Inhalt geändert wird:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=hash_file('md5', $file);?>">
ismavolk
quelle
Huch! Dies wäre für die Leistung und Skalierbarkeit schrecklich, wenn immer alle Ihre CSS / JS-Dateien in den Hauptthread geladen würden, um deren Größe / Hash zu überprüfen.
Dalin
@Dalin Bevor du die Tränen von Gentoo Ricer weinst (eine Linux-Distribution, die dafür bekannt ist, dass sie "schnell geht", weil sie übermäßig aus dem Quellcode kompiliert und auf die Architektur abgestimmt ist), würde ich einen statAnruf tätigen . Ohne Dateisystem-Cache, 16 ns, oben? Mit Cache zuverlässig <8ns. Nanosekunden. Und auf meinem System kann MD5 754 MiB / s verarbeiten, ohne zu blinken. ( openssl speed md5) In Kombination hätte eine 100-KB-CSS-Datei einen zusätzlichen Overhead von… 129µs (Mikrosekunden, 0,1295ms) + 8ns (was nicht wesentlich zur endgültigen Zahl beiträgt) = 129µs.
Amcgregor
Bei weiterer Überlegung ist es mir ein Rätsel, dass die einzige "richtige" Antwort (mit geringster Wartungsbelastung, genauestem / zuverlässigem Verhalten) sowohl die am wenigsten gewählte als auch in einem einzigen Kommentar aus solch fadenscheinigen und unrealistischen Gründen abgelehnt wird.
Amcgregor
Sie und ich arbeiten wahrscheinlich an verschiedenen Websites. Aber ich stehe zu meinem Kommentar. Wenn zu einem bestimmten Zeitpunkt Dutzende von Threads gleichzeitig Webseiten bereitstellen, gibt es meiner Meinung nach bessere Optionen, bei denen Sie nicht einmal in Frage stellen müssen, ob sie skalierbar sind. hash_file('md5', $deployment_counter)oder hash_file('md5', $cache_clear_counter)sind die ersten, die mir in den Sinn kommen.
Dalin