Wyczyść pamięć podręczną w JavaScript

179

Jak wyczyścić pamięć podręczną przeglądarki za pomocą JavaScript?

Wdrożyliśmy najnowszy kod JavaScript, ale nie możemy pobrać najnowszego kodu JavaScript.

Uwaga redakcyjna: to pytanie jest częściowo powtórzone w poniższych miejscach, a odpowiedź na pierwsze z poniższych pytań jest prawdopodobnie najlepsza. Ta zaakceptowana odpowiedź nie jest już idealnym rozwiązaniem.

Jak zmusić przeglądarkę do ponownego załadowania buforowanych plików CSS / JS?

Jak zmusić klientów do odświeżenia plików JavaScript?

Dynamicznie przeładuj lokalne dane źródłowe / json JavaScript

Dylan Brams
źródło
5
Wprawia mnie to w zakłopotanie: „Wdrożyliśmy najnowszy kod javascript, ale nie możemy pobrać najnowszego kodu javascript”
instanceof me
14
Chyba masz na myśli, jak zmusić przeglądarki klienckie do używania najnowszej wersji javascript, a nie jego wersji z pamięci podręcznej - w takim przypadku potrzebujesz odpowiedzi Grega. Jeśli chcesz wiedzieć, jak to zrobić we własnej przeglądarce, to odpowiedź Davida Johnstone'a.
Benjol
4
Typowym podejściem jest dołączanie pliku ?version=xxxdo połączonych plików JS w etapie kompilacji. Każda nowa kompilacja zażąda nowej wersji pliku JS.
Juan Mendes,
1
@JuanMendes To nie zawsze działa. Ten sam krok jest zalecany, gdy ludzie mają problemy z wyświetleniem najnowszej ikony ulubionych. Po prostu nie ma gwarancji, że zadziała.
uSeRnAmEhAhAhAhAhA

Odpowiedzi:

202

Możesz wywołać window.location.reload (true), aby ponownie załadować bieżącą stronę. Zignoruje wszelkie elementy z pamięci podręcznej i pobierze nowe kopie strony, css, obrazów, JavaScript itp. Z serwera. Nie powoduje to wyczyszczenia całej pamięci podręcznej, ale powoduje wyczyszczenie pamięci podręcznej strony, na której się znajdujesz.

Jednak najlepszą strategią jest utworzenie wersji ścieżki lub nazwy pliku, jak wspomniano w różnych innych odpowiedziach. Ponadto, zobacz Revving Filenames: nie używaj querystring z powodów, których nie należy używać ?v=njako schematu wersji.

Kevin Hakanson
źródło
6
Wow, dzięki! Działa to również dobrze w przypadku pamięci podręcznej aplikacji HTML5 ładowanej z pliku cache.manifest. Miałem stary manifest, który nie był usuwany z pamięci, więc jedna przeglądarka, która miała go w pamięci podręcznej, po prostu nie wyświetlała nowszych plików. Wpisałem to w konsoli javascript i działało dobrze. Dzięki!
JayCrossler
2
ale revving poprzez zmianę nazwy pliku ... czy nie oznacza to, że zachowasz wszystkie poprzednie wersje na miejscu? w przeciwnym razie będziesz miał wiele nieudanych prób z wyszukiwarek i czego nie czytać starszych wersji (lub obrazów
Rodolfo
1
jak to się
stało,
1
Czy to to samo, co kliknięcie przycisku odświeżania przez użytkownika?
GMsoF
2
@Manuel Wyłączy dostęp do strony z pamięci podręcznej tylko z dokładnym adresem URL, który wywołałeś lokalizację.reload (prawda). Nigdy nie czyści oryginalnej strony z pamięci podręcznej, ponieważ po prostu dodaje znacznik czasu do nowego żądania, a jeśli inne wywołania są wykonywane asynchronicznie przez tę stronę, te żądania NIE będą miały wyłączonego buforowania. Na przykład. Jeśli odświeżysz stronę za pomocą funkcji reload (true), która ładuje trochę html, a ta strona ma skrypt, który wykonuje drugie wywołanie ajax, aby wyświetlić więcej html na tej samej stronie, drugie żądanie nie będzie miało wyłączonego buforowania.
J. Schei
114

Nie możesz wyczyścić pamięci podręcznej za pomocą javascript. Typowym sposobem jest dołączenie numeru wersji lub ostatniej aktualizacji znacznika czasu do pliku, na przykład:

myscript.123.js

lub

myscript.js?updated=1234567890

Greg
źródło
9
Należy jednak pamiętać, że wiele serwerów proxy nie buforuje pliku, jeśli zawiera ciąg zapytania. Zobacz odpowiedź Kevina Hakansona .
chiborg
4
Jak wyczyścić pamięć podręczną, gdy cały kod HTML został zapisany w pamięci podręcznej? Nie wpłynie to nawet na dodanie numeru wersji z powodu buforowanego kodu HTML.Prosimy o pomoc
Nandakumar
Jeśli nie mogę wyczyścić elementu pamięci podręcznej, dlaczego MDN mówi , że mogę? czego mi brakuje? Spróbowałem tego, co mówi MDN, ale bez powodzenia.
Sнаđошƒаӽ
41

Spróbuj zmienić src pliku JavaScript? Od tego:

<script language="JavaScript" src="js/myscript.js"></script>

Do tego:

<script language="JavaScript" src="js/myscript.js?n=1"></script>

Ta metoda powinna zmusić przeglądarkę do załadowania nowej kopii pliku JS.

Barry Gallagher
źródło
Co robi n = 1?
KyelJmD
nie robi nic poza byciem czymś innym. może to być? 12345 lub? Kyle
Oneezy
Więc nazwa pliku też musi zostać zmieniona? A może po prostu ścieżkę src, którą trzeba zmienić?
Fred A
20

Oprócz buforowania co godzinę lub co tydzień możesz buforować dane zgodnie z danymi pliku.

Przykład (w PHP):

<script src="js/my_script.js?v=<?=md5_file('js/my_script.js')?>"></script>

lub nawet użyj czasu modyfikacji pliku:

<script src="js/my_script.js?v=<?=filemtime('js/my_script.js')?>"></script>
Alexandre T.
źródło
3
Czy mogę zweryfikować, czy rozumiem to poprawnie?: W przypadku opcji 1, gdy plik się zmienia, zmienia się suma kontrolna md5, co następnie zmienia adres URL. Przeglądarka widzi nowy adres URL i inicjuje nowe ładowanie pliku. Dane get dołączone do adresu URL są ignorowane przez serwer. Jeśli tak jest, to cholernie zręcznie.
Colin Brogan
1
Poza tym, czy MD5-ing zużywa dużo procesora plików? Rozważam zrobienie tego na zawsze w pliku css i js, ale nie chciałbym widzieć z tego powodu spadku szybkości serwera.
Colin Brogan
2
Używanie sumy kontrolnej to dobry pomysł, ale należy to zrobić dobrze. Obliczanie tego każdego żądania dla każdego pliku znacząco wpłynie na wydajność. Querystring nie jest również dobry do buforowania, zobacz inne odpowiedzi. Prawidłowym użyciem jest dodanie sumy kontrolnej (części?) Lub numeru wersji do nazwy pliku i zamiast tego użycie nowej nazwy (możesz użyć skryptu kompilacji, aby zrobić to automagicznie podczas wdrażania). Zobacz chrząknięcie , rev i usemin .
Frizi
10

Możesz także wymusić ponowne ładowanie kodu co godzinę, na przykład w PHP:

<?php
echo '<script language="JavaScript" src="js/myscript.js?token='.date('YmdH').'">';
?>

lub

<script type="text/javascript" src="js/myscript.js?v=<?php echo date('YmdHis'); ?>"></script>
Fabien Ménager
źródło
1
cześć, co oznacza „v” i „token”?
GMsoF,
4
@GMsoF to tylko dodatkowy parametr get, który jest używany (w tym przypadku) do informowania przeglądarki, że jest to „inny” plik. Aby przeglądarka odrzuciła wersję z pamięci podręcznej i zamiast tego załadowała tę. Jest to często używane z „datą ostatniej modyfikacji” pliku. Mam nadzieję, że to ma sens ;-)
Jelmer
6

umieść to na końcu swojego szablonu:

var scripts =  document.getElementsByTagName('script');
var torefreshs = ['myscript.js', 'myscript2.js'] ; // list of js to be refresh
var key = 1; // change this key every time you want force a refresh
for(var i=0;i<scripts.length;i++){ 
   for(var j=0;j<torefreshs;j++){ 
      if(scripts[i].src && (scripts[i].src.indexOf(torefreshs[j]) > -1)){
        new_src = scripts[i].src.replace(torefreshs[j],torefreshs[j] + 'k=' + key );
        scripts[i].src = new_src; // change src in order to refresh js
      } 
   }
}
yboussard
źródło
1
proszę wyjaśnić swoje rozwiązanie
Gabriel Espinoza
@GabrielEspinoza przeładowuje pliki za pomocą javascript, co sprawia, że ​​cache są aktualizowane.
Neo Morina
6

spróbuj tego użyć

 <script language="JavaScript" src="js/myscript.js"></script>

Do tego:

 <script language="JavaScript" src="js/myscript.js?n=1"></script>
Daniel
źródło
5

Oto fragment tego, czego używam w moim najnowszym projekcie.

Ze sterownika:

if ( IS_DEV ) {
    $this->view->cacheBust = microtime(true);
} else {
    $this->view->cacheBust = file_exists($versionFile) 
        // The version file exists, encode it
        ? urlencode( file_get_contents($versionFile) )
        // Use today's year and week number to still have caching and busting 
        : date("YW");
}

Z widoku:

<script type="text/javascript" src="/javascript/somefile.js?v=<?= $this->cacheBust; ?>"></script>
<link rel="stylesheet" type="text/css" href="/css/layout.css?v=<?= $this->cacheBust; ?>">

Nasz proces publikowania generuje plik z numerem wersji bieżącej kompilacji. Działa to poprzez kodowanie adresu URL tego pliku i używanie go jako pomijania pamięci podręcznej. W przypadku awarii, jeśli ten plik nie istnieje, używany jest rok i numer tygodnia, dzięki czemu buforowanie nadal działa i będzie odświeżane co najmniej raz w tygodniu.

Ponadto zapewnia to pomijanie pamięci podręcznej przy każdym załadowaniu strony w środowisku programistycznym, dzięki czemu programiści nie muszą martwić się o czyszczenie pamięci podręcznej z jakichkolwiek zasobów (javascript, css, wywołania ajax itp.).

Justin Johnson
źródło
5

lub możesz po prostu odczytać plik js przez serwer za pomocą file_get_contets, a następnie wstawić echo w nagłówku zawartość js

albanx
źródło
4

Może „wyczyszczenie pamięci podręcznej” nie jest tak łatwe, jak powinno. Zamiast czyścić pamięć podręczną w moich przeglądarkach, zdałem sobie sprawę, że „dotknięcie” pliku w rzeczywistości zmieni datę pliku źródłowego zapisanego w pamięci podręcznej na serwerze (Testowane na Edge, Chrome i Firefox), a większość przeglądarek automatycznie pobierze najnowszą, świeżą kopię pliku co jest na twoim serwerze (kod, grafika, wszelkie multimedia). Proponuję po prostu skopiować najbardziej aktualne skrypty na serwerze i „zrobić dotyk rzecz” rozwiązanie przed swoimi przebiegów programu, więc będzie to zmienić datę wszystkich plików problemowych do najbardziej aktualnej daty i czasu, a następnie pobiera nową kopię do Twojej przeglądarki:

<?php
    touch('/www/control/file1.js');
    touch('/www/control/file2.js');
    touch('/www/control/file2.js');
?>

... reszta twojego programu ...

Zajęło mi trochę czasu, aby rozwiązać ten problem (ponieważ wiele przeglądarek działa inaczej na różne polecenia, ale wszystkie sprawdzają czas plików i porównują z pobraną kopią w przeglądarce, jeśli inna data i godzina, odświeży się), jeśli nie może pójść w rzekomy sposób, zawsze istnieje inne użyteczne i lepsze rozwiązanie. Pozdrawiam i szczęśliwego kempingu.

Luis H Cabrejo
źródło
1
Podoba mi się to podejście, ale może wdrażam je w niewłaściwym obszarze? Czy ktoś wie, gdzie to dodać w konfiguracji WordPress? Dodałem go do pliku functions.php z bezpośrednimi linkami do plików JavaScript i CSS, ale nadal musiałem wykonać twarde przeładowanie, aby zmiany zostały zauważone.
flipflopmedia
1
To, co musisz zrobić, to edytować plik index.php w głównym katalogu html wordpress, aby wywołać lub wykonać polecenie Touch () do plików, które chcesz odświeżyć i pobrać. Miałem problemy z małymi plikami pics i js, które utknęły w pamięci podręcznej. Próbowałem większości opisanych metod zwalniania z pamięci, ale najlepszym sposobem jest załadowanie aktualnej, świeżej, poprawnej. Możesz to osiągnąć, wykonując po prostu polecenie „Touch Thing”, ponieważ nie modyfikuje on niczego w pliku, po prostu aktualizuje aktualny czas i datę, więc przeglądarka myśli, że to kolejna wersja pliku i problem został rozwiązany. Działa na większości przeglądarek
Luis H Cabrejo
3

Miałem kłopoty z kodem sugerowanym przez yboussarda. Wewnętrzna pętla j nie działała. Oto zmodyfikowany kod, którego używam z powodzeniem.

function reloadScripts(toRefreshList/* list of js to be refresh */, key /* change this key every time you want force a refresh */) {
    var scripts = document.getElementsByTagName('script');
    for(var i = 0; i < scripts.length; i++) {
        var aScript = scripts[i];
        for(var j = 0; j < toRefreshList.length; j++) {
            var toRefresh = toRefreshList[j];
            if(aScript.src && (aScript.src.indexOf(toRefresh) > -1)) {
                new_src = aScript.src.replace(toRefresh, toRefresh + '?k=' + key);
                // console.log('Force refresh on cached script files. From: ' + aScript.src + ' to ' + new_src)
                aScript.src = new_src;
            }
        }
    }
}
Bryan
źródło
3

Jeśli używasz php, możesz zrobić:

 <script src="js/myscript.js?rev=<?php echo time();?>"
    type="text/javascript"></script>
user3573488
źródło
6
To pytanie nie tylko zostało zadane cztery lata temu, ale miało też lepszą odpowiedź, nawet jeśli nie zostało zaakceptowane.
4
Ponadto ta metoda powodowałaby ponowne pobieranie pliku za każdym razem, niezależnie od rzeczywistego numeru wersji lub zmian wprowadzonych w pliku, co skutecznie całkowicie wyłączałoby buforowanie.
Antti29,
2

Cache.delete () może być używany dla nowych przeglądarek Chrome, Firefox i Opera.

Jay Shah
źródło
Czy to nie jest tylko część API Service Workers?
BanksySan,
@BanksySan z MDN docs:You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec.
Madbreaks
2

Prosimy nie podawać błędnych informacji. Cache API to inny typ pamięci podręcznej niż pamięć podręczna http

Pamięć podręczna HTTP jest uruchamiana, gdy serwer wysyła prawidłowe nagłówki , nie możesz uzyskać dostępu za pomocą javasvipt.

Cache api z drugiej strony jest uruchamiany, kiedy chcesz, jest to przydatne podczas pracy z pracownikiem usług, dzięki czemu można przecinać żądanie i odpowiadać na nie z tego typu pamięci podręcznej patrz: ilustracja 1 ilustracja 2 kurs

Możesz użyć tych technik, aby zawsze mieć świeżą zawartość dla swoich użytkowników:

  1. Użyj location.reload (true) to nie działa dla mnie, więc nie polecam tego.
  2. Użyj Cache API , aby zapisać w pamięci podręcznej i przeciąć żądanie z Service Workerem , uważaj na to, ponieważ jeśli serwer wysłał nagłówki pamięci podręcznej dla plików, które chcesz odświeżyć, przeglądarka odpowie najpierw z pamięci podręcznej HTTP, a jeśli go nie znajdzie, to trafi do sieci, więc możesz skończyć ze starym plikiem
  3. Zmień adres URL z plików stactics, zalecam, aby nadać mu nazwę ze zmianą zawartości plików, używam md5, a następnie konwertuję go na przyjazny ciąg i adres URL, a md5 zmieni się wraz z zawartością pliku, tam może swobodnie wysyłać wystarczająco długo nagłówki pamięci podręcznej HTTP

Trzeci poleciłbym zobaczyć

John Balvin Arias
źródło
2

Możesz również wyłączyć buforowanie przeglądarki za pomocą metatagów HTML, po prostu umieść tagi HTML w sekcji nagłówka, aby uniknąć buforowania strony internetowej podczas kodowania / testowania, a kiedy skończysz, możesz usunąć metatagi.

(w sekcji głównej)

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0"/>

Odśwież swoją stronę po wklejeniu tego w głowie i odśwież również nowy kod javascript.

Ten link daje Ci inne opcje, jeśli ich potrzebujesz http://cristian.sulea.net/blog/disable-browser-caching-with-meta-html-tags/

lub możesz po prostu utworzyć taki przycisk

<button type="button" onclick="location.reload(true)">Refresh</button>

odświeża się i unika buforowania, ale będzie tam na twojej stronie do zakończenia testowania, wtedy możesz go zdjąć. Najlepsza opcja na pięść.

alfmonc
źródło
1

Mam tendencję do tworzenia wersji mojego frameworka, a następnie stosuję numer wersji do skryptów i ścieżek stylów

<cfset fw.version = '001' />
<script src="/scripts/#fw.version#/foo.js"/>
SpliFF
źródło
3
OP nie wspomniał o Coldfusion.
marctrem
@VijayDev 404 dla twojego linku
smarber
1
window.parent.caches.delete("call")

zamknij i otwórz przeglądarkę po wykonaniu kodu w konsoli.

Apoorv
źródło
1
Proszę o wyjaśnienie, co to jest „wezwanie” w powyższym kodzie?
Anand Rockzz
@AnandRockzz to niemożliwe, cache api to po prostu nowy typ pamięci podręcznej, którą można zarządzać za pomocą javascipt, więc aby usunąć coś stamtąd, zapisałeś to wcześniej, patrz developer.mozilla.org/en-US/docs/ Sieć / API / Pamięć podręczna
John Balvin Arias,
1

window.location.reload(true)wydaje się być przestarzały w standardzie HTML5. Jednym ze sposobów na zrobienie tego bez używania ciągów zapytań jest użycie Clear-Site-Datanagłówka , który wydaje się być ustandaryzowany .

Mój Boże
źródło
0

Ponieważ pamięć podręczna przeglądarki przechowuje ten sam link, należy dodać losowy koniec adresu URL. new Date().getTime()wygenerować inny numer.

Poprostu dodaj new Date().getTime() koniec linku jak połączenie

'https://stackoverflow.com/questions.php?' + new Date().getTime()

Wynik: https://stackoverflow.com/questions.php?1571737901173

EMAM HASAN
źródło
Witamy w SO! Twoja odpowiedź jest niejasna. Proszę go edytować. Tego typu odpowiedzi oparte na linku powinny być komentowane na wypadek, gdyby link zniknął.
David García Bodego