JavaScript'te önbelleği temizleme


179

JavaScript ile tarayıcı önbelleğini nasıl temizlerim?

En son JavaScript kodunu konuşlandırdık ancak en son JavaScript kodunu alamıyoruz.

Editoryal Not: Bu soru aşağıdaki yerlerde yarı kopyalanmıştır ve aşağıdaki soruların ilkindeki cevap muhtemelen en iyisidir. Kabul edilen bu cevap artık ideal çözüm değildir.

Tarayıcı, önbelleğe alınmış CSS / JS dosyalarını yeniden yüklemeye nasıl zorlanır?

İstemcileri JavaScript dosyalarını yenilemeye nasıl zorlayabilirim?

Yerel Javascript kaynağı / json verilerini dinamik olarak yeniden yükle


5
Bu beni şaşırtıyor: "En son javascript kodunu konuşlandırdık, ancak en son javascript kodunu alamıyoruz"
instanceof me

14
İstemci tarayıcılarını önbelleğe alınmış sürümlerini değil, en son javascript sürümünüzü kullanmaya nasıl zorlayacağınızı düşünüyorum - bu durumda Greg'in cevabına ihtiyacınız var. Kendi tarayıcınızda nasıl yapılacağını bilmek istiyorsanız, David Johnstone'un cevabı.
Benjol


4
Yaygın olarak kullanılan yaklaşım, ?version=xxxJS bağlantılı dosyalarınıza bir derleme adımı yoluyla a eklemek . Her yeni derleme JS dosyasının yeni bir sürümünü ister.
Juan Mendes

1
@JuanMendes Bu her zaman işe yaramaz. Aynı adım, insanların en son favicon'u görmeye çalışırken sorunları olduğunda da önerilir. Sadece çalışacağı garanti edilmez.
Ocak

Yanıtlar:


202

Geçerli sayfayı yeniden yüklemek için window.location.reload (true) öğesini çağırabilirsiniz . Önbelleğe alınmış öğeleri yok sayar ve sayfanın, css, resimler, JavaScript vb. Yeni kopyalarını sunucudan alır. Bu, tüm önbelleği temizlemez, ancak bulunduğunuz sayfa için önbelleği temizleme etkisine sahiptir.

Bununla birlikte, en iyi stratejiniz yolu veya dosya adını diğer çeşitli yanıtlarda belirtildiği gibi versiyonlamaktır. Ayrıca, bkz. Dosya Adlarını Değiştirme:?v=n sürüm oluşturma düzeniniz olarak kullanılmama nedenlerinden dolayı querystring kullanmayın .


6
Vay canına, teşekkürler! Bu, bir cache.manifest dosyasından yüklenen bir HTML5 Uygulama Önbelleği için de iyi çalışır. Bellekten kaldırılmayan eski bir bildirimim vardı, bu yüzden önbelleğe sahip bir tarayıcı daha yeni dosyaları göstermeyecekti. Javascript konsolunda bu yazdı ve iyi çalıştı. Teşekkürler!
JayCrossler

2
ancak dosya adını değiştirerek revize etmek ... önceki sürümlerin tümünü yerinde tutmayacak mısınız? Aksi takdirde, arama motorlarından çok sayıda başarısız deneme alırsınız ve eski sürümleri (veya yer imi eklenmiş / bağlantılı görselleri)
okumazsınız

1
bu nasıl düşünmedim, tank
osdamv

1
Bu, kullanıcının yenile düğmesini tıklamasıyla aynı mıdır?
GMsoF

2
@Manuel Yalnızca location.reload (true) adını verdiğiniz tam URL'nin önbelleğinden sayfaya erişmeyi devre dışı bırakır. Yeni isteğe hiçbir zaman damgası eklediğinden orijinal sayfayı önbellekten asla temizlemez ve bu sayfa tarafından eşzamansız olarak yapılan başka çağrılar varsa, bu isteklerin önbellekleme davranışları DEVRE DIŞI BIRAKILMAZ. Örneğin. Bazı html yükleyen bir sayfayı yeniden yükleme (true) ile yenilerseniz ve bu sayfada aynı sayfada daha fazla html görüntülenmesi için ikinci bir ajax çağrısı yapan bir komut dosyası varsa, ikinci istek önbelleğe alınmasını devre dışı bırakmaz.
J. Schei

114

Javascript ile önbelleği temizleyemezsiniz. Sık kullanılan bir yol, düzeltme numarasını veya en son güncellenen zaman damgasını dosyaya şu şekilde eklemektir:

myscript.123.js

veya

myscript.js?updated=1234567890


9
Bununla birlikte, birçok proxy'nin bir sorgu dizesi olduğunda bir dosyayı önbelleğe almadığını unutmayın. Kevin Hakanson'un cevabına bakınız .
chiborg

4
Tüm HTML önbelleğe alındığında önbelleği nasıl temizleyebilirim? Bu sürüm numarası, çünkü önbelleğe HTML.Please yardım eklense bile etkileyecek alışkanlık
Nandakumar

Bir önbellek öğesini temizleyemezsem, MDN neden yapabileceğimi söylüyor ? Neyi kaçırıyorum? MDN'nin söylediklerini denedim ama şans yok.
Sнаđошƒаӽ

41

JavaScript dosyasının src'sini değiştirmeyi deneyin? Bundan:

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

Buna:

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

Bu yöntem, tarayıcınızı JS dosyasının yeni bir kopyasını yüklemeye zorlamalıdır.


N = 1 ne yapar?
KyelJmD

farklı bir şey olmak dışında hiçbir şey yapmaz. olabilir? 12345 veya? Kyle
Oneezy

Yani dosya adının da değiştirilmesi mi gerekiyor? Veya sadece değiştirilmesi gereken src yolu mu?
Fred A

20

Her saat veya her hafta önbellekleme dışında, dosya verilerine göre önbellekleme yapabilirsiniz.

Örnek (PHP'de):

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

hatta dosya değiştirme zamanını kullanın:

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

3
Bunu doğru anladığımı doğrulayabilir miyim ?: Seçenek 1 ile, dosya değiştiğinde, md5 sağlama toplamı karması değişir ve bu da URL'yi değiştirir. Tarayıcı yeni bir URL görür ve yeni bir dosya yükü başlatır. URL'ye eklenen get verileri sunucu tarafından yoksayılır. Eğer durum buysa, oldukça saçma.
Colin Brogan

1
Ayrıca, MD5-ing bütün bir dosya işlemcisini yoğun mu? Bunu hiç css ve js dosyası için yapmayı düşünüyorum, ancak bu nedenle sunucu hızına bir hit görmek nefret ediyorum.
Colin Brogan

2
Bir sağlama toplamı kullanmak iyi bir fikirdir, ancak doğru yapılmalıdır. Her dosya için her isteği hesaplamak performansınızı önemli ölçüde etkileyecektir. Sorgu dizesi de önbelleğe almak için iyi değildir, diğer yanıtlara bakın. Doğru kullanım, dosya adına bir sağlama toplamı (? Parçası) veya sürüm numarası eklemek ve bunun yerine bu yeni adı kullanmaktır (bunu dağıtım sırasında otomatik olarak yapmak için bir oluşturma komut dosyası kullanabilirsiniz). Bkz hırıltı , rev ve usemin .
Frizi

10

Ayrıca kodu PHP'de her saat gibi yeniden yüklenmeye zorlayabilirsiniz:

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

veya

<script type="text/javascript" src="js/myscript.js?v=<?php echo date('YmdHis'); ?>"></script>

1
merhaba, "v" ve "jeton" ne anlama geliyor?
GMsoF

4
@GMsoF, tarayıcıya "farklı" bir dosya olduğunu söylemek için kullanılan ek bir get parametresidir (bu örnekte). Böylece tarayıcı önbelleğe alınmış sürümü atar ve bunun yerine bunu yükler. Bu genellikle bir dosyanın "son değiştirilme tarihi" ile kullanılır. Umarım bu mantıklıdır ;-)
Jelmer

6

bunu şablonunuzun sonuna ekleyin:

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
      } 
   }
}

1
Lütfen çözümünüzle ilgili biraz açıklama yapın
Gabriel Espinoza

@GabrielEspinoza, önbelleklerin güncellenmesini sağlayan javascript kullanarak dosyaları yeniden yükler.
Neo Morina

6

bunu kullanmayı dene

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

Buna:

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

5

İşte son projem için kullandığım bir parçacık.

Denetleyiciden:

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");
}

Görünümden:

<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; ?>">

Yayınlama sürecimiz, mevcut yapının revizyon numarası olan bir dosya oluşturur. Bu, söz konusu dosyayı kodlayan ve önbellek bozucu olarak kullanan URL ile çalışır. Bir başarısızlık olarak, bu dosya yoksa, önbellekleme hala çalışacak şekilde yıl ve hafta numarası kullanılır ve haftada en az bir kez yenilenir.

Ayrıca, bu, geliştirme ortamındayken her sayfa yükü için önbellek bozma sağlar, böylece geliştiriciler herhangi bir kaynak (javascript, css, ajax çağrıları, vb.) İçin önbelleği temizlemek konusunda endişelenmek zorunda kalmazlar.


5

veya sadece js dosyasını file_get_contets ile sunucuya okuyabilir ve sonra js içeriğini başlığa yankı koyabilirsiniz


4

Belki "önbelleği temizlemek" olması gerektiği kadar kolay değildir. Tarayıcılarımdaki önbelleği temizlemek yerine , dosyaya "dokunmanın" sunucuda önbelleğe alınan kaynak dosyanın tarihini değiştireceğini (Edge, Chrome ve Firefox'ta test edildi) ve çoğu tarayıcının otomatik olarak en güncel yeni kopyasını indireceğini fark ettim . sunucunuzda ne var (kod, grafikler de herhangi bir multimedya). Programınız çalıştırılmadan önce sunucudaki en güncel komut dosyalarını kopyalamanızı ve "dokunma işlemini yap" çözümünü kullanmanızı öneririm , böylece tüm sorun dosyalarınızın tarihini en güncel tarih ve saate değiştirir, ardından yeni bir kopyasını indirir tarayıcınıza:

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

... programınızın geri kalanı ...

Bu sorunu çözmem biraz zaman aldı (birçok tarayıcı farklı komutlara farklı davranıyor, ancak hepsi dosya saatlerini kontrol ediyor ve farklı tarih ve saat varsa yenilemeyi yapacak olan tarayıcınızda indirdiğiniz kopyayla karşılaştırıyor), sözde doğru yola devam edemez, her zaman başka bir kullanılabilir ve daha iyi bir çözüm vardır. Saygılarımızla ve mutlu kamp.


1
Bu yaklaşımı seviyorum ama belki de bunu yanlış alanda uyguluyorum? Herkes bunu bir WordPress kurulumuna nereye ekleyeceğini biliyor mu? JavaScript ve CSS dosyalarına doğrudan bağlantılar ile function.php dosyasına ekledim, ancak değişikliklerin fark edilmesi için hala zor bir yeniden yükleme yapmak zorunda kaldım.
flipflopmedia

1
Yapmanız gereken ana html wordpress dizininizde, yenilemek ve indirmeniz gereken dosyaları Touch () komutunu çağırmak veya yürütmek için index.php'nizi düzenleyin. Önbellekte sıkışmış küçük resimler ve js dosyaları ile ilgili sorunlar vardı. Bellekten serbest bırakmak için açıklanan yöntemlerin çoğunu denedim, ancak en iyi yol geçerli bir taze doğru olanı yüklemek. Dosyadaki hiçbir şeyi değiştirmediği için sadece "Touch Thing" i yaparak geçerli saati ve tarihi güncellediğini, böylece tarayıcınızın dosyanın başka bir sürümünü ve sorunun çözüldüğünü düşünmesini sarar. Çoğu tarayıcıda çalışır
Luis H Cabrejo

3

Yboussard tarafından önerilen kod ile bazı sorunlar vardı. İç j döngüsü işe yaramadı. İşte başarıyla kullandığım değiştirilmiş kod.

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;
            }
        }
    }
}

3

Eğer php kullanıyorsanız yapabilirsiniz:

 <script src="js/myscript.js?rev=<?php echo time();?>"
    type="text/javascript"></script>

6
Bu soru sadece dört yıl önce sorulmakla kalmadı, kabul edilmese bile daha iyi bir cevabı vardı.

4
Ayrıca, bu yöntem, gerçek revizyon numarasından veya dosyada yapılan değişikliklerden bağımsız olarak dosyayı her seferinde yeniden indirir ve bu da önbelleği tamamen devre dışı bırakır.
Antti29

2

Cache.delete () yeni krom, firefox ve opera için kullanılabilir.


Bu Hizmet Çalışanlarının API'sının sadece bir parçası değil mi?
BanksySan

MDN belgelerinden You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec.
@BanksySan

2

Lütfen yanlış bilgi vermeyin. Önbellek API'si http önbelleğinden farklı bir önbellek türüdür

Sunucu doğru başlıkları gönderdiğinde HTTP önbelleği tetiklenir , javasvipt ile erişemezsiniz.

Öte yandan önbellek api , istediğiniz zaman tetiklenir, servis çalışanı ile çalışırken faydalıdır, böylece isteği kesebilir ve bu tür bir önbellekten cevaplayabilirsiniz bkz: ilustration 1 ilustration 2 course

Kullanıcılarınızda her zaman yeni bir içeriğe sahip olmak için bu teknikleri kullanabilirsiniz:

  1. Location.reload kullanın (true) bu benim için çalışmıyor, bu yüzden tavsiye etmem.
  2. Önbelleğe kaydetmek ve isteği servis çalışanıyla kesiştirmek için Önbellek API'sini kullanın , sunucuya önbellek başlıklarını gönderirse , tarayıcı önce HTTP önbelleğinden yanıt verir, ve bulamazsa, ağa gidecektir, böylece eski dosya ve eski dosya ile sonuçlanabilir
  3. Stactics dosyalarından URL'yi değiştirin, tavsiyem, dosya içeriğinizdeki değişiklikle adlandırmanız gerekir, md5 kullanıyorum ve sonra dize ve url'ye dönüştürüyorum ve md5 dosyanın içeriği ile değişecek, orada HTTP önbellek başlıklarını yeterince uzun süre gönderebilir

Ben üçüncü birini tavsiye ediyorum görmek


2

Ayrıca, kodlama / test işlemi sırasında web sayfasının önbelleğe alınmasını önlemek için meta HTML etiketleri ile tarayıcı önbelleğe almayı devre dışı bırakabilirsiniz, işiniz bittiğinde meta etiketleri kaldırabilirsiniz.

(baş bölümünde)

<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"/>

Bunu başa yapıştırdıktan sonra sayfanızı yenileyin ve yeni javascript kodunu da yenileyin.

Bu bağlantı size ihtiyacınız varsa başka seçenekler de sunar http://cristian.sulea.net/blog/disable-browser-caching-with-meta-html-tags/

ya da böyle bir düğme oluşturabilirsiniz

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

yenilenir ve önbelleğe alınmasını önler, ancak testi bitirinceye kadar sayfanızda olacaktır, sonra çıkarabilirsiniz. Yumruk seçeneği en iyisidir.


1

Çerçevemi sürümlendirme eğilimindeyim, ardından sürüm numarasını komut dosyasına ve stil yollarına uygularım

<cfset fw.version = '001' />
<script src="/scripts/#fw.version#/foo.js"/>

3
OP, Coldfusion'dan bahsetmedi.
marctrem

Senin bağlantı için @VijayDev 404
smarber

1
window.parent.caches.delete("call")

Konsolda kodu yürüttükten sonra tarayıcıyı kapatıp açın.


1
Biraz açıklama lütfen, yukarıdaki kodda "çağrı" nedir?
Anand Rockzz

@AnandRockzz mümkün değil, önbellek api sadece javascipt ile yönetilebilen yeni bir önbellek türüdür, bu nedenle oradan bir şey silmek için, developer.mozilla.org/en-US/docs/ adresini ziyaret etmeden önce kaydetmişsinizdir. Web / API / Önbellek
John Balvin Arias


0

Tarayıcı önbelleği aynı bağlantıya neden olursa, url'nin rastgele bir sayı sonuna eklemelisiniz. new Date().getTime()farklı bir sayı üretebilir.

Sadece new Date().getTime()bağlantının sonunu çağrı gibi ekleyin

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

Çıktı: https://stackoverflow.com/questions.php?1571737901173


SO hoş geldiniz! Cevabınız belirsiz. Lütfen düzenleyin. Bağlantıya dayalı bu tür yanıtlar, bağlantının kaybolması durumunda yorumlanmalıdır.
David García Bodego
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.