Frage

Hintergrund

Ich schreibe und verwende ein sehr einfaches CGI-basiertes (Perl) Content-Management-Tool für zwei Pro-Bono-Websites.Es stellt dem Website-Administrator HTML-Formulare für Veranstaltungen zur Verfügung, in denen er die Felder (Datum, Ort, Titel, Beschreibung, Links usw.) ausfüllt und speichert.Auf diesem Formular erlaube ich dem Administrator, ein Bild im Zusammenhang mit der Veranstaltung hochzuladen.Auf der HTML-Seite, auf der das Formular angezeigt wird, zeige ich auch eine Vorschau des hochgeladenen Bildes (HTML-img-Tag).

Das Problem

Das Problem tritt auf, wenn der Administrator das Bild ändern möchte.Er müsste nur auf die Schaltfläche „Durchsuchen“ klicken, ein neues Bild auswählen und auf „OK“ klicken.Und das funktioniert gut.

Sobald das Bild hochgeladen ist, übernimmt mein Back-End-CGI den Upload und lädt das Formular ordnungsgemäß neu.

Das Problem ist, dass das Bild angezeigt wird nicht Erfrische dich.Das alte Bild wird immer noch angezeigt, obwohl die Datenbank das richtige Bild enthält.Ich habe es auf die Tatsache eingegrenzt, dass das BILD im Webbrowser zwischengespeichert wird.Wenn der Administrator in Firefox/Explorer/Safari auf die Schaltfläche „Neu laden“ klickt, wird alles ordnungsgemäß aktualisiert und das neue Bild wird angezeigt.

Meine Lösung: Funktioniert nicht

Ich versuche, den Cache zu steuern, indem ich eine HTTP-Expires-Anweisung mit einem Datum schreibe, das sehr weit in der Vergangenheit liegt.

Expires: Mon, 15 Sep 2003 1:00:00 GMT

Denken Sie daran, dass ich auf der administrativen Seite bin und es mir eigentlich egal ist, ob das Laden der Seiten etwas länger dauert, weil sie immer abgelaufen sind.

Aber auch das funktioniert nicht.

Anmerkungen

Beim Hochladen eines Bildes wird dessen Dateiname nicht in der Datenbank gespeichert.Es wird umbenannt in Bild.jpg (um Dinge bei der Verwendung einfach herauszufinden).Beim Ersetzen des vorhandenen Bildes durch ein neues ändert sich auch der Name nicht.Lediglich der Inhalt der Bilddatei ändert sich.

Der Webserver wird vom Hosting-Dienstleister/ISP bereitgestellt.Es verwendet Apache.

Frage

Gibt es eine Möglichkeit, den Webbrowser zu zwingen, KEINE Dinge von dieser Seite zwischenzuspeichern, nicht einmal Bilder?

Ich jongliere mit der Option, den Dateinamen tatsächlich in der Datenbank zu speichern.Wenn das Bild geändert wird, ändert sich auf diese Weise auch die Quelle des IMG-Tags.Dies erfordert jedoch viele Änderungen auf der gesamten Website und ich mache das lieber nicht, wenn ich eine bessere Lösung habe.Dies funktioniert auch immer noch nicht, wenn das neu hochgeladene Bild denselben Namen hat (sagen wir, das Bild wurde ein wenig mit Photoshop bearbeitet und erneut hochgeladen).

War es hilfreich?

Lösung

Armin Ronacher hat die richtige Idee. Das Problem ist, zufällige Zeichenfolge kollidieren können. Ich würde verwenden:

<img src="picture.jpg?1222259157.415" alt="">

Wo „1222259157.415“ auf dem Server die aktuelle Zeit.
Generieren Zeit von Javascript mit performance.now() oder von Python mit time.time()

Andere Tipps

Einfache fix: Bringen Sie eine zufällige Abfrage-String auf dem Bild:

<img src="foo.cgi?random=323527528432525.24234" alt="">

Was die HTTP RFC sagt:

Cache-Control: no-cache

Aber das funktioniert nicht so gut:)

Ich verwende PHP-Datei geändert Zeitfunktion , zum Beispiel:

echo <img  src='Images/image.png?" . filemtime('Images/image.png') . "'  />";

Wenn Sie das Bild ändern, dann das neue Bild verwendet wird, eher als die im Cache gespeichert, aufgrund eines anderen modifizierten Zeitstempel haben.

Ich würde verwenden:

<img src="picture.jpg?20130910043254">

, wobei "20130910043254" ist der Zeitpunkt der letzten Änderung der Datei.

  

Wenn Sie ein Bild hochladen, wird der Dateiname nicht in der Datenbank gespeichert. Es wird als Image.jpg umbenannt (einfach Dinge, wenn es verwendet wird). Wenn es mit einem neuen das vorhandene Bild zu ersetzen, wird der Name nicht ändern. Nur der Inhalt der Image-Datei ändert.

Ich denke, es gibt zwei Arten von einfachen Lösungen: 1) solche, die erste (einfache Lösungen in den Sinn kommen, weil sie mit) leicht zu kommen sind, 2) diejenigen, die Sie Dinge über das Denken am Ende mit nach (weil sie sind einfach zu bedienen). Anscheinend wird man nicht immer davon profitieren, wenn Sie die Dinge zu denken, wählten über. Aber die zweiten Optionen eher unterschätzt werden, glaube ich. Man denke nur, warum php so populär ist;)

Sie können ein Proxy-Skript zum Servieren Bilder schreiben - das ist allerdings etwas mehr Arbeit. Etwas gefällt das:

HTML:

<img src="image.php?img=imageFile.jpg&some-random-number-262376" />

Script:

// PHP
if( isset( $_GET['img'] ) && is_file( IMG_PATH . $_GET['img'] ) ) {

  // read contents
  $f = open( IMG_PATH . $_GET['img'] );
  $img = $f.read();
  $f.close();

  // no-cache headers - complete set
  // these copied from [php.net/header][1], tested myself - works
  header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Some time in the past
  header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
  header("Cache-Control: no-store, no-cache, must-revalidate"); 
  header("Cache-Control: post-check=0, pre-check=0", false); 
  header("Pragma: no-cache"); 

  // image related headers
  header('Accept-Ranges: bytes');
  header('Content-Length: '.strlen( $img )); // How many bytes we're going to send
  header('Content-Type: image/jpeg'); // or image/png etc

  // actual image
  echo $img;
  exit();
}

Eigentlich entweder No-Cache-Header oder Zufallszahl an Bild src sollte ausreichend sein, aber da wir wollen kugelsicher sein ..

Ich bin ein NEUER Programmierer, aber hier ist, was ich mir ausgedacht habe, um zu verhindern, dass der Browser meine Webcam-Ansichten zwischenspeichert und festhält:

<meta Http-Equiv="Cache" content="no-cache">
<meta Http-Equiv="Pragma-Control" content="no-cache">
<meta Http-Equiv="Cache-directive" Content="no-cache">
<meta Http-Equiv="Pragma-directive" Content="no-cache">
<meta Http-Equiv="Cache-Control" Content="no-cache">
<meta Http-Equiv="Pragma" Content="no-cache">
<meta Http-Equiv="Expires" Content="0">
<meta Http-Equiv="Pragma-directive: no-cache">
<meta Http-Equiv="Cache-directive: no-cache">

Ich bin mir nicht sicher, was in welchem ​​Browser funktioniert, aber bei einigen funktioniert es:IE:Funktioniert, wenn die Webseite aktualisiert wird und wenn die Website erneut besucht wird (ohne Aktualisierung).CHROM:Funktioniert nur, wenn die Webseite aktualisiert wird (auch nach einem erneuten Besuch).SAFARI und iPad:Funktioniert nicht, ich muss den Verlauf und die Webdaten löschen.

Irgendwelche Ideen zu SAFARI/iPad?

verwenden class = "no-cache"

Beispiel html:

<div>
    <img class="NO-CACHE" src="images/img1.jpg" />
    <img class="NO-CACHE" src="images/imgLogo.jpg" />
</div>

jQuery:

    $(document).ready(function ()
    {           
        $('.NO-CACHE').attr('src',function () { return $(this).attr('src') + "?a=" + Math.random() });
    });

javascript:

var nods = document.getElementsByClassName('NO-CACHE');
for (var i = 0; i < nods.length; i++)
{
    nods[i].attributes['src'].value += "?a=" + Math.random();
}

Ergebnis: src = "images / img1.jpg" => src = "images / img1.jpg? a = ,08749723793963926"

  

Wenn Sie ein Bild hochladen, wird der Dateiname nicht in der Datenbank gespeichert. Es wird umbenannt als Image.jpg (einfach Dinge, wenn es verwendet wird).

Ändern Sie diese, und Sie haben Ihr Problem behoben. Ich benutze Zeitstempel, wie bei den oben genannten Lösungen vorgeschlagen: Image- .jpg

Vermutlich was auch immer Probleme, die Sie, indem sie die gleichen Dateinamen für das Bildmotiv vermeiden kann überwunden werden, aber man nicht sagen, was sie sind.

ich alle Antworten rund um das Internet und die besten geprüft zu sein schien: (es ist eigentlich nicht)

<img src="image.png?cache=none">

auf den ersten.

Wenn Sie jedoch hinzufügen Cache = none Parameter (die statisch "none" Wort ist), ist es nicht etwas bewirken, Browser lädt noch aus dem Cache.

Lösung für dieses Problem war:

<img src="image.png?nocache=<?php echo time(); ?>">

, wo Sie im Grunde Unix-Zeitstempel in dem die Parameter dynamisch und keinen Cache zu machen, es hat funktioniert.

Allerdings war mein Problem ein wenig anders: Ich lade on the fly php Kartenbild erzeugt wird, und zum Steuern der Seite mit $ _GET Parameter. Ich wollte das Bild aus dem Cache gelesen werden, wenn die URL GET-Parameter gleich bleiben, und nicht Cache, wenn die GET-Parameter ändern.

Um dieses Problem zu lösen, musste ich _GET $ Hash aber da es Array hier ist die Lösung:

$chart_hash = md5(implode('-', $_GET));
echo "<img src='/images/mychart.png?hash=$chart_hash'>";

Bearbeiten :

Obwohl die obige Lösung funktioniert gut, manchmal will man die im Cache gespeicherte Version dienen, bis die Datei geändert wird. (Mit der obigen Lösung, deaktiviert es den Cache für das Bild vollständig) Also, um im Cache gespeicherte Bild vom Browser zu dienen, bis es zu einer Änderung in der Bilddatei verwendet wird:

echo "<img src='/images/mychart.png?hash=" . filemtime('mychart.png') . "'>";
  

filemtime () bekommt Dateibearbeitungszeit.

Ihr Problem ist, dass trotz der Expires: Header Ihr Browser erneut mit seiner In-Memory-Kopie des Bildes aus, bevor sie aktualisiert wurde, anstatt selbst seinen Cache zu überprüfen.

hatte ich eine sehr ähnliche Situation Produktbilder im Admin-Backend für eine Speicher-like-Website hochladen, und in meinem Fall habe ich beschlossen, die beste Option Javascript zu verwenden war ein Bild Auffrischen zu zwingen, ohne irgendwelche der URL-modifizierende mit Techniken andere Leute haben hier bereits erwähnt. Stattdessen habe ich die Bild-URL in eine versteckte IFRAME, genannt location.reload(true) auf dem Fenster des IFRAME, und dann auf der Seite mein Bild ersetzt. Dies erzwingt eine Aktualisierung des Bildes, nicht nur auf der Seite, die ich bin, aber auch auf alle späteren Seiten, die ich besuchen -. Ohne entweder Client oder Server alle URL Abfragezeichenfolgeflag oder Fragmentbezeichner Parameter merken müssen

Ich stellte einige Code dies in meiner Antwort zu tun? hier .

Fügen Sie einen Zeitstempel <img src="picture.jpg?t=<?php echo time();?>">

wird immer geben Sie Ihre Datei eine Zufallszahl am Ende und stoppen sie das Caching

Mit dem Potenzial für schlecht benommen transparente Proxies in zwischen Ihnen und dem Kunden, der einzige Weg, völlig zu garantieren, dass die Bilder nicht im Cache gespeichert werden ist sie eine einzigartige uri zu geben, so etwas wie einen Zeitstempel-Tagging auf als Query-String oder als Teil des Pfades.

Wenn das Zeitstempel der letzten Aktualisierungszeit des Bildes entspricht, dann können Sie zwischenspeichern, wenn Sie benötigen und dazu dienen, das neue Bild gerade zur rechten Zeit.

Ich gehe davon aus ursprünglicher Frage in Bezug auf Bilder mit Text Informationen gespeichert. Also, wenn Sie Zugriff auf einen Textkontext haben, wenn src = Erzeugung ... URL betrachtet store / verwenden CRC32 das Bild statt sinnlos zufälligen oder Zeitstempel-Bytes. Wenn dann die Seite mit vielen Bildern angezeigt wird, werden nur dann aktualisiert, Bilder neu geladen werden. Schließlich, wenn CRC Speicherung nicht möglich ist, kann es auf die URL zur Laufzeit berechnet und angehängt werden.

Aus meiner Sicht deaktivieren Bilder-Caching ist eine schlechte Idee. Überhaupt.

Das eigentliche Problem hier ist - wie Browser zwingen Bild zu aktualisieren, wenn es auf einer Server-Seite wurde aktualisiert.

Auch aus meiner persönlichen Sicht ist die beste Lösung, die direkten Zugriff auf Bilder zu deaktivieren. Statt Bilder Zugriff über serverseitige Filter / Servlet / andere ähnliche Werkzeuge / Dienstleistungen.

In meinem Fall ist es ein Rest-Service, das Bild zurück und legt ETag in der Antwort. Der Service hält Hash aller Dateien, wenn die Datei geändert wird, Hash aktualisiert wird. Es funktioniert perfekt in allen modernen Browsern. Ja, es braucht Zeit, es zu implementieren, aber es lohnt sich.

Die einzige Ausnahme - sind Favicons. Aus irgendwelchen Gründen, funktioniert es nicht. Ich konnte nicht Browser erzwingen seinen Cache von Server-Seite zu aktualisieren. ETags, Cache Control, Ablaufdatum, Pragma-Header, half nichts.

In diesem Fall das Hinzufügen einige zufällige / Version Parameter in URL, wie es scheint, ist die einzige Lösung.

Im Idealfall sollten Sie auf eine Schaltfläche / Keybinding / Menü jeder Webseite mit einer Option fügen Sie Inhalt zu synchronisieren.

so zu tun, würden Sie den Überblick über Ressourcen halten, die synchronisiert werden müssen, und verwenden Sie entweder xhr die Bilder mit einem dynamischen Abfragezeichenfolgeflag zu sondieren, oder ein Bild zur Laufzeit mit src erstellen eine dynamische Abfragezeichenfolgeflag verwenden. Dann mit einem Rundfunkmechanismus benachrichtigen alle Komponenten der Web-Seiten, die die Ressource verwenden, um zu aktualisieren, um die Ressource mit einem dynamischen Abfragezeichenfolgeflag seiner URL angehängt zu verwenden.

Ein naives Beispiel sieht wie folgt aus:

Normalerweise wird das Bild angezeigt und zwischengespeichert, aber wenn der Benutzer die Taste gedrückt wird, eine XHR-Anforderung wird mit einer Zeit an die Ressource gesendet angefügt Abfragezeichenfolgen; da die Zeit auf jeder Presse, anders zu sein angenommen werden, wird es sicher, dass der Browser-Cache umgehen wird, da es nicht darum, ob die Ressource dynamisch auf der Serverseite basierend auf der Abfrage generiert wird sagen kann, oder wenn es sich um eine statisch Ressource, die Abfrage ignoriert.

Das Ergebnis ist, dass Sie alle mit vermeiden können Ihre Benutzer, die Sie mit Ressourcen bombardieren fordert die ganze Zeit, aber zugleich erlauben, einen Mechanismus für die Nutzer, ihre Ressourcen zu aktualisieren, wenn sie vermuten, dass sie nicht synchron sind.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="mobile-web-app-capable" content="yes" />        
    <title>Resource Synchronization Test</title>
    <script>
function sync() {
    var xhr = new XMLHttpRequest;
    xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {            
            var images = document.getElementsByClassName("depends-on-resource");

            for (var i = 0; i < images.length; ++i) {
                var image = images[i];
                if (image.getAttribute('data-resource-name') == 'resource.bmp') {
                    image.src = 'resource.bmp?i=' + new Date().getTime();                
                }
            }
        }
    }
    xhr.open('GET', 'resource.bmp', true);
    xhr.send();
}
    </script>
  </head>
  <body>
    <img class="depends-on-resource" data-resource-name="resource.bmp" src="resource.bmp"></img>
    <button onclick="sync()">sync</button>
  </body>
</html>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top