tło
Piszę i używam bardzo prostego narzędzia do zarządzania treścią opartego na CGI (Perl) dla dwóch witryn pro-bono. Udostępnia administratorowi strony formularze HTML do wydarzeń, w których wypełnia pola (data, miejsce, tytuł, opis, linki itp.) I zapisuje je. Na tym formularzu pozwalam administratorowi na przesłanie zdjęcia związanego z wydarzeniem. Na stronie HTML wyświetlającej formularz pokazuję również podgląd wgranego zdjęcia (tag HTML img).
Problem
Problem pojawia się, gdy administrator chce zmienić obrazek. Musiałby po prostu nacisnąć przycisk „Przeglądaj”, wybrać nowe zdjęcie i wcisnąć ok. I to działa dobrze.
Po załadowaniu obrazu mój back-end CGI obsługuje przesyłanie i ponownie ładuje formularz.
Problem polega na tym, że wyświetlany obraz nie jest odświeżany. Stary obraz jest nadal wyświetlany, mimo że baza danych zawiera właściwy obraz. Ograniczyłem to do faktu, że OBRAZ JEST CACHOWANY w przeglądarce internetowej. Jeśli administrator naciśnie przycisk RELOAD w przeglądarce Firefox / Explorer / Safari, wszystko zostanie poprawnie odświeżone i nowy obraz po prostu się pojawi.
Moje rozwiązanie - nie działa
Próbuję kontrolować pamięć podręczną, pisząc instrukcję HTTP Expires z datą bardzo dawną w przeszłości.
Expires: Mon, 15 Sep 2003 1:00:00 GMT
Pamiętaj, że jestem po stronie administracyjnej i nie obchodzi mnie, czy ładowanie stron trwa trochę dłużej, ponieważ zawsze wygasają.
Ale to też nie działa.
Uwagi
Podczas przesyłania obrazu jego nazwa pliku nie jest przechowywana w bazie danych. Został zmieniony na Image.jpg (aby po prostu rozwiązać problem podczas korzystania z niego). Podczas zastępowania istniejącego obrazu nowym, nazwa również się nie zmienia. Zmienia się tylko zawartość pliku obrazu.
Serwer WWW jest udostępniany przez usługę hostingową / dostawcę usług internetowych. Używa Apache.
Pytanie
Czy istnieje sposób, aby zmusić przeglądarkę internetową, aby NIE buforowała rzeczy z tej strony, nawet obrazów?
Żongluję opcją „zapisania nazwy pliku” w bazie danych. W ten sposób, jeśli obraz zostanie zmieniony, zmieni się również src tagu IMG. Wymaga to jednak wielu zmian w całej witrynie i raczej nie robię tego, jeśli mam lepsze rozwiązanie. Ponadto, to nadal nie zadziała, jeśli nowy przesłany obraz ma tę samą nazwę (powiedzmy, że obraz został trochę przerobiony w Photoshopie i ponownie przesłany).
źródło
Odpowiedzi:
Armin Ronacher ma dobry pomysł. Problem polega na tym, że przypadkowe ciągi mogą się zderzać. Użyłbym:
Gdzie „1222259157.415” to bieżący czas na serwerze.
Generuj czas za pomocą JavaScript z
performance.now()
lub przez Python ztime.time()
źródło
Prosta poprawka: dołącz losowy ciąg zapytania do obrazu:
Co mówi HTTP RFC:
Ale to nie działa tak dobrze :)
źródło
Używam funkcji czasu modyfikacji pliku PHP , na przykład:
Jeśli zmienisz obraz, zostanie użyty nowy obraz, a nie zapisany w pamięci podręcznej, ze względu na inny zmodyfikowany znacznik czasu.
źródło
Użyłbym:
gdzie „20130910043254” to czas modyfikacji pliku.
Myślę, że istnieją dwa rodzaje prostych rozwiązań: 1) te, które przychodzą na myśl pierwsze (proste rozwiązania, ponieważ są łatwe do wymyślenia), 2) takie, które przychodzą do głowy po przemyśleniu (ponieważ są łatwe do posługiwać się). Najwyraźniej nie zawsze odniesiesz korzyści, jeśli zdecydujesz się przemyśleć sprawy. Uważam jednak, że druga opcja jest raczej niedoceniana. Pomyśl tylko, dlaczego
php
jest tak popularny;)źródło
images.php
.). Ten skrypt musi być ponownie generowany przy każdym zatwierdzeniu i eliminuje narzut związany z określaniem czasów modyfikacji plików.użyj Class = "NO-CACHE"
przykładowy html:
jQuery:
javascript:
Wynik: src = "images / img1.jpg" => src = "images / img1.jpg? A = 0.08749723793963926"
źródło
Możesz napisać skrypt proxy do wyświetlania obrazów - to jednak trochę więcej pracy. Coś takiego:
HTML:
Scenariusz:
Właściwie albo nagłówki bez pamięci podręcznej lub losowa liczba w źródle obrazu powinny być wystarczające, ale ponieważ chcemy być kuloodporni ...
źródło
Jestem NOWYM koderem, ale oto, co wymyśliłem, aby powstrzymać przeglądarkę przed buforowaniem i utrzymywaniem widoków z mojej kamery internetowej:
Nie jestem pewien, co działa w jakiej przeglądarce, ale działa w niektórych: IE: działa, gdy strona jest odświeżana i kiedy ponownie odwiedzana jest witryna (bez odświeżania). CHROME: działa tylko po odświeżeniu strony internetowej (nawet po ponownej wizycie). SAFARI i iPad: nie działa, muszę wyczyścić historię i dane internetowe.
Jakieś pomysły na SAFARI / iPad?
źródło
Zmień to i naprawiłeś swój problem. Używam znaczników czasu, tak jak w rozwiązaniach zaproponowanych powyżej: Image- <timestamp> .jpg
Prawdopodobnie wszelkie problemy, których unikniesz, zachowując tę samą nazwę pliku obrazu, można rozwiązać, ale nie mówisz, jakie one są.
źródło
Sprawdziłem wszystkie odpowiedzi w sieci i wydawało się, że najlepsza z nich brzmi: (właściwie nie jest)
najpierw.
Jeśli jednak dodasz parametr cache = none (które jest statycznym słowem „none”), to nic nie zmienia, przeglądarka nadal ładuje się z pamięci podręcznej.
Rozwiązaniem tego problemu było:
gdzie zasadniczo dodajesz uniksowy znacznik czasu, aby parametr był dynamiczny i nie miał pamięci podręcznej, zadziałało.
Jednak mój problem był trochę inny: ładowałem w locie wygenerowany obraz wykresu php i kontrolowałem stronę za pomocą parametrów $ _GET. Chciałem, aby obraz był odczytywany z pamięci podręcznej, gdy parametr URL GET pozostaje taki sam, i nie buforował, gdy zmieniają się parametry GET.
Aby rozwiązać ten problem, musiałem haszować $ _GET, ale ponieważ jest to tablica, oto rozwiązanie:
Edycja :
Chociaż powyższe rozwiązanie działa dobrze, czasami chcesz udostępniać wersję z pamięci podręcznej do momentu zmiany pliku. (przy powyższym rozwiązaniu całkowicie wyłącza pamięć podręczną tego obrazu) Tak więc, aby wyświetlać buforowany obraz z przeglądarki, DO DOPÓKI nastąpi zmiana w użyciu pliku obrazu:
źródło
filemtime
Rozwiązanie jest lepsze, ponieważ teżmd5
zajmuje dużo mocy obliczeniowej.Twój problem polega na tym, że pomimo
Expires:
nagłówka Twoja przeglądarka ponownie wykorzystuje znajdującą się w pamięci kopię obrazu sprzed aktualizacji, zamiast sprawdzać pamięć podręczną.Miałem bardzo podobną sytuację, gdy ładowałem zdjęcia produktów w zapleczu administracyjnym dla witryny podobnej do sklepu, aw moim przypadku zdecydowałem, że najlepszą opcją jest użycie javascript do wymuszenia odświeżenia obrazu, bez użycia jakichkolwiek technik modyfikacji adresu URL innych osób już tutaj wspomniałem. Zamiast tego umieściłem adres URL obrazu w ukrytej ramce IFRAME, wywołanej
location.reload(true)
w oknie IFRAME, a następnie zastąpiłem mój obraz na stronie. Wymusza to odświeżenie obrazu, nie tylko na stronie, na której jestem, ale także na wszystkich późniejszych stronach, które odwiedzam - bez konieczności zapamiętywania parametrów zapytania URL lub identyfikatora fragmentu przez klienta lub serwer.Zamieściłem jakiś kod, aby zrobić to w mojej odpowiedzi tutaj .
źródło
Dodaj znacznik czasu
<img src="picture.jpg?t=<?php echo time();?>">
zawsze nada plikowi losową liczbę na końcu i zatrzyma buforowanie
źródło
Ze względu na możliwość złego zachowania przezroczystych serwerów proxy między Tobą a klientem, jedynym sposobem na całkowitą gwarancję, że obrazy nie będą buforowane, jest nadanie im unikalnego identyfikatora URI, coś w rodzaju oznaczania znacznika czasu jako ciągu zapytania lub jako części ścieżka.
Jeśli ten znacznik czasu odpowiada czasowi ostatniej aktualizacji obrazu, możesz buforować, kiedy zajdzie taka potrzeba, i wyświetlać nowy obraz we właściwym czasie.
źródło
Zakładam, że oryginalne pytanie dotyczy obrazów przechowywanych z pewnymi informacjami tekstowymi. Tak więc, jeśli masz dostęp do kontekstu tekstowego podczas generowania src = ... url, rozważ przechowywanie / używanie CRC32 bajtów obrazu zamiast bezsensownego znacznika losowego lub czasu. Następnie, jeśli wyświetlana jest strona z dużą ilością obrazów, tylko zaktualizowane obrazy zostaną ponownie załadowane. Ostatecznie, jeśli przechowywanie CRC jest niemożliwe, można je obliczyć i dołączyć do adresu URL w czasie wykonywania.
źródło
Z mojego punktu widzenia wyłączenie buforowania obrazów to zły pomysł. W ogóle.
Głównym problemem jest tutaj - jak zmusić przeglądarkę do aktualizacji obrazu, gdy został zaktualizowany po stronie serwera.
Z mojego osobistego punktu widzenia najlepszym rozwiązaniem jest wyłączenie bezpośredniego dostępu do obrazów. Zamiast tego uzyskuj dostęp do obrazów za pośrednictwem filtru po stronie serwera / serwletu / innych podobnych narzędzi / usług.
W moim przypadku jest to usługa odpoczynku, która zwraca obraz i dołącza ETag w odpowiedzi. Usługa przechowuje hash wszystkich plików, jeśli plik zostanie zmieniony, zostanie zaktualizowany. Działa doskonale we wszystkich nowoczesnych przeglądarkach. Tak, wdrożenie go wymaga czasu, ale warto.
Jedyny wyjątek - to favicony. Z pewnych powodów to nie działa. Nie mogłem zmusić przeglądarki do aktualizacji pamięci podręcznej po stronie serwera. ETags, Cache Control, Expires, Pragma headers, nic nie pomogło.
W tym przypadku wydaje się, że dodanie jakiegoś parametru losowego / version do adresu URL jest jedynym rozwiązaniem.
źródło
Najlepiej byłoby dodać przycisk / klawisz / menu do każdej strony internetowej z opcją synchronizacji treści.
Aby to zrobić, możesz śledzić zasoby, które mogą wymagać synchronizacji, i albo użyć xhr do sondowania obrazów za pomocą dynamicznego zapytania, albo utworzyć obraz w czasie wykonywania za pomocą src przy użyciu dynamicznego zapytania. Następnie użyj mechanizmu rozgłaszania, aby powiadomić wszystkie komponenty stron internetowych, które używają zasobu do aktualizacji, aby używały zasobu z dynamicznym zapytaniem dołączonym do adresu URL.
Naiwny przykład wygląda tak:
Zwykle obraz jest wyświetlany i przechowywany w pamięci podręcznej, ale jeśli użytkownik naciśnie przycisk, do zasobu wysyłane jest żądanie xhr z dołączonym zapytaniem o czas; ponieważ można założyć, że czas jest inny przy każdym naciśnięciu, upewni się, że przeglądarka ominie pamięć podręczną, ponieważ nie może stwierdzić, czy zasób jest generowany dynamicznie po stronie serwera na podstawie zapytania, czy też jest statyczny zasób, który ignoruje zapytanie.
W rezultacie możesz uniknąć sytuacji, w której wszyscy użytkownicy będą przez cały czas bombardować Cię żądaniami zasobów, ale jednocześnie umożliwisz użytkownikom aktualizowanie ich zasobów, jeśli podejrzewają, że nie są zsynchronizowani.
źródło
Zrobiłem skrypt PHP, który automatycznie dodaje sygnatury czasowe do wszystkich obrazów na stronie HTML. Wystarczy, że umieścisz ten skrypt na swoich stronach. Cieszyć się!
http://alv90.altervista.org/how-to-force-the-browser-not-to-cache-images/
źródło
Musisz użyć unikalnych nazw plików. Lubię to
Ale ta technika oznacza wysokie użycie serwera i marnotrawstwo przepustowości. Zamiast tego należy użyć numeru wersji lub daty. Przykład:
Ale chcesz, aby nigdy nie wyświetlał obrazu z pamięci podręcznej. W tym celu, jeśli strona nie korzysta z pamięci podręcznej strony , jest to możliwe po stronie PHP lub serwera.
Jednak nadal nie jest to skuteczne. Powód: pamięć podręczna przeglądarki ... Ostatnią, ale najbardziej skuteczną metodą jest natywny JAVASCRIPT. Ten prosty kod znajduje wszystkie obrazy z klasą „NO-CACHE” i sprawia, że obrazy są prawie niepowtarzalne. Umieść to między tagami skryptu.
STOSOWANIE
WYNIK (y) Jak to
źródło