Czy mogę w jakiś sposób umieścić kod na mojej stronie, aby gdy ktoś odwiedził witrynę, wyczyścił pamięć podręczną przeglądarki, aby mógł zobaczyć zmiany?
Użyte języki: ASP.NET, VB.NET i oczywiście HTML, CSS i jQuery.
Czy mogę w jakiś sposób umieścić kod na mojej stronie, aby gdy ktoś odwiedził witrynę, wyczyścił pamięć podręczną przeglądarki, aby mógł zobaczyć zmiany?
Użyte języki: ASP.NET, VB.NET i oczywiście HTML, CSS i jQuery.
Odpowiedzi:
Jeśli tak jest .css
i .js
zmienia się, jednym ze sposobów na „pomijanie pamięci podręcznej” jest dodanie czegoś takiego jak „ _versionNo
” do nazwy pliku dla każdej wersji. Na przykład:
script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.
Lub alternatywnie zrób to po nazwie pliku:
script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.
Możesz sprawdzić ten link, aby zobaczyć, jak to może działać.
script.js?v=1.2
. (Lub jeśli nie śledzisz wersji, użyj czasu ostatniej modyfikacji pliku, co jest jeszcze łatwiejsze do zrobienia). Nie jestem pewien, czy to właśnie miał na myśli poprzedni komentator!
<link />
dynamicznie renderować tagi i wstrzykiwać wersję aplikacji jako parametr ciągu zapytania. Alternatywnie, niektóre CMSy będą miały „wersję zasobów klienta” jako dołączone ustawienie dla całego CMS - administrator witryny może ręcznie zwiększyć tę wersję nr, a aktualizacje CMS mogą również automatycznie ją zaktualizować. Konkluzja: musisz dynamicznie renderować adresy URL plików.
Zajrzyj do kontroli pamięci podręcznej, a tag META utraci ważność .
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">
Inną powszechną praktyką jest dołączanie ciągle zmieniających się ciągów na końcu żądanych plików. Na przykład:
<script type="text/javascript" src="main.js?v=12392823"></script>
To stare pytanie, ale myślę, że wymaga ono bardziej aktualnej odpowiedzi, ponieważ teraz istnieje sposób na większą kontrolę nad buforowaniem stron internetowych.
W aplikacjach internetowych offline (czyli tak naprawdę dowolnej witrynie HTML5)applicationCache.swapCache()
można używać do aktualizowania wersji witryny z pamięci podręcznej bez konieczności ręcznego przeładowywania strony.
Oto przykład kodu z Przewodnika dla początkujących na temat używania pamięci podręcznej aplikacji w HTML5 Rocks, wyjaśniający, jak zaktualizować użytkowników do najnowszej wersji witryny:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
// Swap it in and reload the page to get the new hotness.
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
Zobacz także Korzystanie z pamięci podręcznej aplikacji w Mozilla Developer Network, aby uzyskać więcej informacji.
Rzeczy szybko się zmieniają w sieci. To pytanie zostało zadane w 2009 r., Aw 2012 r. Opublikowałem aktualizację dotyczącą nowego sposobu rozwiązania problemu opisanego w pytaniu. Minęły kolejne 4 lata i teraz wydaje się, że jest już przestarzałe. Dzięki cgaldiolo za wskazanie tego w komentarzach.
Obecnie, od lipca 2016 r., HTML Standard, sekcja 7.9, Offline aplikacje internetowe zawiera ostrzeżenie o wycofaniu:
Ta funkcja jest właśnie usuwana z platformy internetowej. (Jest to długi proces, który trwa wiele lat.) Odradza się obecnie korzystanie z dowolnych funkcji aplikacji internetowych offline. Zamiast tego użyj pracowników serwisu.
Podobnie jest z używaniem pamięci podręcznej aplikacji w sieci Mozilla Developer Network, do której odwoływałem się w 2012 roku:
Przestarzałe
Ta funkcja została usunięta ze standardów internetowych. Chociaż niektóre przeglądarki mogą go obsługiwać, jest on w trakcie usuwania. Nie używaj go w starych lub nowych projektach. Korzystające z niego strony lub aplikacje internetowe mogą w dowolnym momencie ulec awarii.
Zobacz także Błąd 1204581 - Dodaj powiadomienie o wycofaniu AppCache, jeśli włączono przechwytywanie pobierania pracownika usługi .
Nie jako taki. Jedną z metod jest wysłanie odpowiednich nagłówków podczas dostarczania treści, aby zmusić przeglądarkę do ponownego załadowania:
Upewnienie się, że strona internetowa nie jest buforowana we wszystkich przeglądarkach.
Jeśli szukasz "cache header"
lub coś podobnego tutaj na SO, znajdziesz przykłady specyficzne dla ASP.NET.
Innym, mniej czystym, ale czasem jedynym sposobem, jeśli nie można kontrolować nagłówków po stronie serwera, jest dodanie losowego parametru GET do wywoływanego zasobu:
myimage.gif?random=1923849839
W przypadku zasobów statycznych właściwym buforowaniem byłoby użycie parametrów zapytania o wartości każdego wdrożenia lub wersji pliku. Spowoduje to wyczyszczenie pamięci podręcznej po każdym wdrożeniu.
/Content/css/Site.css?version={FileVersionNumber}
Oto przykład ASP.NET MVC.
<link href="@Url.Content("~/Content/Css/Reset.css")?version=@this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />
Nie zapomnij zaktualizować wersji zestawu.
?version=@ViewContext.Controller.GetType().Assembly.GetName().Version
Miałem podobny problem i tak go rozwiązałem:
W index.html
pliku dodałem manifest:
<html manifest="cache.manifest">
W <head>
sekcji zawarto skrypt aktualizujący pamięć podręczną:
<script type="text/javascript" src="update_cache.js"></script>
W <body>
sekcji wstawiłem funkcję onload:
<body onload="checkForUpdate()">
W cache.manifest
umieściłem wszystkie pliki, które chcę buforować. Ważne jest teraz, że działa w moim przypadku (Apache), po prostu aktualizując za każdym razem komentarz „wersja”. Jest także opcja nazywania plików za pomocą „? Ver = 001” lub czegoś na końcu nazwy, ale nie jest to konieczne . Zmiana tylko # version 1.01
wyzwala zdarzenie aktualizacji pamięci podręcznej.
CACHE MANIFEST
# version 1.01
style.css
imgs/logo.png
#all other files
Ważne jest, aby uwzględniać 1., 2. i 3. punkty tylko w index.html. Inaczej
GET http://foo.bar/resource.ext net::ERR_FAILED
występuje, ponieważ każdy plik „podrzędny” próbuje buforować stronę, gdy strona jest już buforowana.
W update_cache.js
pliku umieściłem ten kod:
function checkForUpdate()
{
if (window.applicationCache != undefined && window.applicationCache != null)
{
window.applicationCache.addEventListener('updateready', updateApplication);
}
}
function updateApplication(event)
{
if (window.applicationCache.status != 4) return;
window.applicationCache.removeEventListener('updateready', updateApplication);
window.applicationCache.swapCache();
window.location.reload();
}
Teraz po prostu zmieniasz pliki i oczywiście musisz zaktualizować komentarz do wersji. Teraz odwiedzając stronę index.html zaktualizujesz pamięć podręczną.
Części rozwiązania nie są moje, ale znalazłem je przez Internet i zestawiłem tak, aby działało.
Miałem przypadek, w którym robiłem zdjęcia klientom online i musiałbym zaktualizować div, jeśli zdjęcie zostanie zmienione. Przeglądarka wciąż wyświetlała stare zdjęcie. Wykorzystałem więc hack wywołania losowej zmiennej GET, która za każdym razem byłaby unikalna. Tutaj jest, jeśli to może komukolwiek pomóc
<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...
EDYCJA Jak zauważyli inni, poniższe jest znacznie bardziej wydajnym rozwiązaniem, ponieważ przeładuje obrazy tylko wtedy, gdy zostaną zmienione, identyfikując tę zmianę według rozmiaru pliku:
<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
Wiele odpowiedzi nie ma sensu - większość programistów zdaje sobie sprawę, że wyłączenie pamięci podręcznej jest nieefektywne. Jednak istnieje wiele typowych okoliczności, w których wydajność nie jest ważna, a domyślne zachowanie pamięci podręcznej jest poważnie zepsute.
Obejmują one zagnieżdżone, iteracyjne testowanie skryptów (duże!) I zepsute obejścia oprogramowania innych firm. Żadne z podanych tutaj rozwiązań nie jest odpowiednie, aby rozwiązać takie powszechne scenariusze. Większość przeglądarek internetowych jest zbyt agresywnym buforowaniem i nie zapewnia rozsądnych sposobów uniknięcia tych problemów.
<meta http-equiv="pragma" content="no-cache" />
Zobacz także /programming/126772/how-to-force-a-web-browser-not-to-cache-images
Aktualizacja adresu URL do następującego działa dla mnie:
/custom.js?id=1
Dodając unikalny numer po ?id=
i zwiększając go o nowe zmiany, użytkownicy nie muszą naciskać, CTRL + F5
aby odświeżyć pamięć podręczną. Alternatywnie możesz dołączyć wersję hash lub string bieżącej godziny lub Epoki po?id=
Coś jak ?id=1520606295
Oto strona MDSN na temat ustawiania buforowania w ASP.NET.
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True
If Response.Cache.VaryByParams("Category") Then
'...
End If
Nie jestem pewien, czy to naprawdę może ci pomóc, ale tak właśnie powinno działać buforowanie w dowolnej przeglądarce. Gdy przeglądarka żąda pliku, powinna zawsze wysyłać żądanie do serwera, chyba że istnieje tryb „offline”. Serwer odczyta niektóre parametry, takie jak data modyfikacji lub etagi.
Serwer zwróci odpowiedź 304 o błędzie NIEZMODYFIKOWANY, a przeglądarka będzie musiała użyć pamięci podręcznej. Jeśli etag nie sprawdza się po stronie serwera lub data modyfikacji jest niższa od bieżącej daty modyfikacji, serwer powinien zwrócić nową treść z nową datą modyfikacji lub etagami lub obydwoma.
Jeśli do przeglądarki nie są wysyłane żadne dane buforowania, myślę, że zachowanie nie jest określone, przeglądarka może buforować plik, który nie informuje o tym, jak są buforowane. Jeśli w odpowiedzi ustawisz parametry buforowania, pliki będą buforowane poprawnie, a serwer może zwrócić błąd 304 lub nową zawartość.
Tak właśnie należy to zrobić. Używanie losowych parametrów lub numeru wersji w adresach URL jest bardziej jak hack niż cokolwiek innego.
http://www.checkupdown.com/status/E304.html http://en.wikipedia.org/wiki/HTTP_ETag http://www.xpertdeveloper.com/2011/03/last-modified-header-vs- expire-header-vs-etag /
Po przeczytaniu zobaczyłem, że jest także data ważności. Jeśli masz problem, być może masz ustawiony termin ważności. Innymi słowy, kiedy przeglądarka zbuforuje twój plik, ponieważ ma on datę ważności, nie powinien być zmuszony żądać go ponownie przed tą datą. Innymi słowy, nigdy nie poprosi pliku na serwer i nigdy nie otrzyma 304 niezmodyfikowanego. Będzie po prostu używał pamięci podręcznej, aż do osiągnięcia daty ważności lub wyczyszczenia pamięci podręcznej.
Zgaduję, że masz jakiś termin ważności i powinieneś użyć ostatnio zmodyfikowanych etagów lub ich kombinacji i upewnić się, że nie ma daty wygaśnięcia.
Jeśli ludzie często odświeżają się, a plik nie jest często zmieniany, rozsądnie jest ustawić dużą datę ważności.
Moje 2 centy!
Wdrożyłem to proste rozwiązanie, które działa dla mnie (jeszcze nie w środowisku produkcyjnym):
function verificarNovaVersio() {
var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
$.ajax({
url: "./versio.txt"
, dataType: 'text'
, cache: false
, contentType: false
, processData: false
, type: 'post'
}).done(function(sVersioFitxer) {
console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
location.reload(true);
}
});
}
Mam mały plik, w którym znajdują się pliki HTML:
„versio.txt”:
v00.5.0014
Ta funkcja jest wywoływana na wszystkich moich stronach, więc podczas ładowania sprawdza, czy wartość wersji localStorage jest niższa niż bieżąca wersja i wykonuje
location.reload(true);
... aby wymusić przeładowanie z serwera zamiast z pamięci podręcznej.
(oczywiście zamiast localStorage możesz używać plików cookie lub innego trwałego miejsca do przechowywania klientów)
Wybrałem to rozwiązanie ze względu na jego prostotę, ponieważ zachowanie tylko jednego pliku „versio.txt” wymusi ponowne załadowanie całej witryny.
Metoda queryString jest trudna do wdrożenia i jest również buforowana (jeśli zmienisz z wersji 1.1 na poprzednią wersję, ładuje się z pamięci podręcznej, oznacza to, że pamięć podręczna nie jest opróżniana, utrzymując wszystkie poprzednie wersje w pamięci podręcznej).
Jestem trochę nowicjuszem i doceniam twoje profesjonalne sprawdzenie i sprawdzenie, aby upewnić się, że moja metoda jest dobrym podejściem.
Mam nadzieję, że to pomoże.
Oprócz ustawienia Cache-control: no-cache, powinieneś również ustawić nagłówek Expires na -1, jeśli chcesz, aby lokalna kopia była odświeżana za każdym razem (niektóre wersje IE wydają się tego wymagać).
Zobacz HTTP Cache - sprawdź na serwerze, zawsze wysyłając If-Modified-Since
Istnieje jedna sztuczka, której można użyć: sztuczka polega na dodaniu parametru / łańcucha do nazwy pliku w znaczniku skryptu i zmianie go podczas zmiany pliku.
<script src="myfile.js?version=1.0.0"></script>
Przeglądarka interpretuje cały ciąg jako ścieżkę do pliku, mimo że co następuje po „?” są parametrami. Więc wat dzieje się teraz, gdy następnym razem, gdy zaktualizujesz plik, po prostu zmień numer w tagu skryptu na swojej stronie internetowej (przykład <script src="myfile.js?version=1.0.1"></script>
), a każda przeglądarka użytkowników zobaczy plik zmienił się i weź nową kopię.
Czy zmusić przeglądarki do wyczyszczenia pamięci podręcznej lub ponownego załadowania poprawnych danych?Wypróbowałem większość rozwiązań opisanych w stackoverflow, niektóre działają, ale po pewnym czasie ostatecznie buforuje i wyświetla poprzednio załadowany skrypt lub plik. Czy istnieje inny sposób, który wyczyści pamięć podręczną (css, js itp.) I faktycznie działa we wszystkich przeglądarkach?
Do tej pory stwierdziłem, że określone zasoby mogą być ponownie ładowane indywidualnie, jeśli zmienisz datę i godzinę w swoich plikach na serwerze. „Czyszczenie pamięci podręcznej” nie jest tak łatwe, jak powinno być. Zamiast wyczyścić pamięć podręczną w moich przeglądarkach, zdałem sobie sprawę, że „dotknięcie” buforowanych plików serwera faktycznie zmieni datę i godzinę pliku źródłowego buforowanego na serwerze (testowane na Edge, Chrome i Firefox) i większość przeglądarek automatycznie pobierze najwięcej aktualna świeża kopia zawartości serwera (kod, grafika i multimedia). Sugeruję po prostu skopiowanie najbardziej aktualnych skryptów na serwerze i rozwiązanie „wykonaj czynności dotykowe” przed uruchomieniem programu, aby zmienił datę wszystkich plików powodujących problemy na najbardziej aktualną datę i godzinę, a następnie pobierze nową kopię do przeglądarki:
<?php
touch('/www/sample/file1.css');
touch('/www/sample/file2.js');
?>
potem ... reszta twojego programu ...
Zajęło mi trochę czasu, aby rozwiązać ten problem (ponieważ wiele przeglądarek zachowuje się inaczej w stosunku do różnych poleceń, ale wszystkie sprawdzają czas plików i porównują z pobraną kopią w przeglądarce, jeśli inna data i godzina przeprowadzą odświeżenie), jeśli nie może pójść we właściwy sposób, zawsze istnieje inne przydatne i lepsze rozwiązanie. Pozdrawiam i wesołego biwakowania. Przy okazji touch (); lub alternatywy działają w wielu językach programowania, w tym w javascript bash sh php, i można je włączyć lub wywołać w formacie HTML.
Czy chcesz wyczyścić pamięć podręczną, czy po prostu upewnij się, że bieżąca (zmieniona?) Strona nie jest buforowana?
Jeśli to drugie, powinno być tak proste jak
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">