AJAX'ın Beklenmeyen Önbelleğe Alınması IE8 ile sonuçlanıyor


135

Bir JQuery Ajax isteği Internet Explorer önbellek sonuçları ile ciddi bir sorun yaşıyorum.

Web sayfamda, kullanıcı yeni bir sayfaya her gittiğinde güncellenen bir başlığım var. Sayfa yüklendikten sonra bunu yaparım

$.get("/game/getpuzzleinfo", null, function(data, status) {
    var content = "<h1>Wikipedia Maze</h1>";
    content += "<p class='endtopic'>Looking for <span><a title='Opens the topic you are looking for in a separate tab or window' href='" + data.EndTopicUrl + "' target='_blank'>" + data.EndTopic + "<a/></span></p>";
    content += "<p class='step'>Step <span>" + data.StepCount + "</span></p>";
    content += "<p class='level'>Level <span>" + data.PuzzleLevel.toString() + "</span></p>";
    content += "<p class='startover'><a href='/game/start/" + data.PuzzleId.toString() + "'>Start Over</a></p>";

    $("#wikiheader").append(content);

}, "json");

Yalnızca sayfaya başlık bilgisi ekler. Www.wikipediamaze.com adresine gidip giriş yapıp yeni bir bulmacayı başlatarak kontrol edebilirsiniz .

Test ettiğim her tarayıcıda (Google Chrome, Firefox, Safari, Internet Explorer) IE dışında harika çalışıyor . Eveything ilk kez IE'de iyi enjekte edilir , ancak bundan sonra asla çağrı yapmaz /game/getpuzzleinfo. Sanki sonuçları önbelleğe almış gibi.

$.post("/game/getpuzzleinfo", ...IE çağrısını değiştirirseniz iyi alır. Ama sonra Firefox çalışmayı bıraktı.

Birisi IE'nin neden $.getajax çağrılarımı önbelleğe aldığına dair biraz ışık tutabilir mi?

GÜNCELLEME

Aşağıdaki öneriye göre, sorunumu düzelten ajax isteğimi değiştirdim:

$.ajax({
    type: "GET",
    url: "/game/getpuzzleinfo",
    dataType: "json",
    cache: false,
    success: function(data) { ... }
});

8
Bunu sorduğun için teşekkürler. Bu tarayıcı davranışını suskun biriyim.
jjohn

1
İyi soru ve gerçekten harika bir web sitesi. İyi bir fikir.
MikeMurko

Yanıtlar:


177

IE, Ajax yanıtlarını agresif bir şekilde önbelleğe almasıyla ünlüdür. JQuery kullanırken genel bir seçenek belirleyebilirsiniz:

$.ajaxSetup({
    cache: false
});

jQuery, istek sorgusu dizesine rasgele bir değer eklemesine neden olarak IE'nin yanıtı önbelleğe almasını engeller.

Önbelleğe almak istediğiniz yerde devam eden başka Ajax çağrılarınız varsa, bunun da bu kişiler için devre dışı bırakılacağını unutmayın. Bu durumda, $ .ajax () yöntemini kullanarak geçiş yapın ve bu seçeneği gerekli istekler için açıkça etkinleştirin.

Daha fazla bilgi için http://docs.jquery.com/Ajax/jQuery.ajaxSetup adresine bakın .


1
Ayrıca, URL'lerinizin sonuna bir zaman damgası da ekleyebilirsiniz. JQuery'nin neden bu yaklaşıma uymadığından emin değilim.
Eric Johnson

14
@Eric: jQuery dahili olarak bunu yapar - "cache: false" seçeneği sadece bunu yapmasını söyler.
NickFitz

Jquery'de neden varsayılan olarak açık değil?
Speedplane

Sadece bir çağrı ile IE 8 ana sayfasını istemeye çalıştığınızda önbellek seçenekleri çalışmadığını fark ettim /. /index.phpTam URL olarak veya ne olursa olsun değiştirin . Ya da kendiniz gibi bazı sahte params ekleyin/?f=f
Hugo Delsing

8

Gibi marr75 söz, GET'ın önbelleğe alınır.

Bununla mücadele etmenin birkaç yolu var. Yanıt başlığını değiştirmenin yanı sıra, hedeflenen URL'nin sonuna rastgele oluşturulmuş bir sorgu dizesi değişkeni de ekleyebilirsiniz. Bu şekilde IE, her istendiğinde farklı bir URL olduğunu düşünecektir.

Bunu yapmanın birden fazla yolu vardır (kullanma Math.random(), tarihte bir değişiklik vb.).

İşte bunu yapmanın bir yolu:

var oDate = new Date();
var sURL = "/game/getpuzzleinfo?randomSeed=" + oDate.getMilliseconds();
$.get(sURL, null, function(data, status) {
    // your work
});

3

Alır her zaman önbelleğe alınabilir. İşe yarayabilecek bir strateji, yanıt üstbilgisini düzenlemek ve istemciye bilgileri önbelleğe almamasını veya önbelleğin çok yakında dolmasını söylemektir.


Güzel bir fikre benziyor. Bunu nasıl yapabilirim?
Micah

1
Bu yüklü bir soru, sunucu tarafı kodunuza bağlıdır. Biraz rehberlik için "HTTP başlıklarının listesi" wikipedia girişine bakın. Örnekler: Önbellek Denetimi: önbellek yok Sona erme tarihi: Per, 01 Ara 1994 16:00:00 GMT Temel olarak bu yanıt başlıklarını http yanıtınıza eklemeniz gerekir. ASP.NET, Ruby ve PHP'de oldukça basit. Kullandığınız sunucu tarafı diline bakın + yanıt başlıklarını değiştirin.
marr75

3
Ayrıca, ve bu Jquery hiç bir eleştiri değil (ben bu kütüphaneyi seviyorum), rastgele bir sorgu dizesi parametresi ekleme yöntemi güvenli ama istemciye kaba (asla kullanılmayacak önbellek öğeleri üzerinde tutarak onları bırakabilirsiniz tekrar).
marr75

2

Ashx sayfası arıyorsanız, aşağıdaki kodla sunucuda önbelleğe almayı da devre dışı bırakabilirsiniz:

context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); 

1

ajax aramaları için yaptığım budur:

var url = "/mypage.aspx";
// my other vars i want to add go here
url = url + "&sid=" + Math.random();
// make ajax call

benim için gayet iyi çalışıyor.


1

NickFitz iyi bir cevap veriyor, ancak IE9'da da önbelleği kapatmanız gerekiyor. Sadece IE8 ve IE9'u hedeflemek için bunu yapabilirsiniz;

<!--[if lte IE 9]>
<script>
    $.ajaxSetup({
        cache: false
    });
</script>
<![endif]-->

0

Buradaki cevaplar jQuery kullanan veya herhangi bir nedenle doğrudan xmlHttpRequest nesnesini kullanan kişiler için çok faydalıdır ...

Otomatik olarak oluşturulan Microsoft hizmeti proxy'sini kullanıyorsanız çözümü basit değildir.

İşin püf noktası, olay işleyicisindeki Sys.Net.WebRequestManager.add_invokingRequest yöntemini kullanmaktır.

networkRequestEventArgs._webRequest._url = networkRequestEventArgs._webRequest._url + '&nocache=' + new Date().getMilliseconds(); 

Bu konuda blog yazdım: http://yoavniran.wordpress.com/2010/04/27/ie-caching-ajax-results-how-to-fix/


0

Sadece ExtJS kullanarak bu sorunla ilgili bir blog yazdım ( http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html )

Ben geleneksel sorgu dizesi params (? Param = değer) kullanamazdım belirli bir url yeniden yazma biçimini kullanıyordu gibi sorun, bu yüzden yayınlanan değişken olarak önbellek bozma parametresini yazmak vardı ..... Ben düşünürdüm POST değişkenlerini kullanmanın GET'ten biraz daha güvenli olduğunu, çünkü birçok MVC çerçevesinin deseni kullandığından

protokol: // host / denetleyici / eylem / Param1 / param2

ve böylece değişken adının değere eşlenmesi kaybolur ve parametreler basitçe yığınlanır ... böylece GET önbellek bozucu parametresi kullanılır

yani protokol: // ana bilgisayar / denetleyici / eylem / param1 / param2 / no_cache122300201

no_cache122300201, varsayılan değeri olabilen bir $ param3 parametresi ile karıştırılabilir

yani

ortak işlev eylemi ($ param1, $ param2, $ param3 = "varsayılan değer") {//..//}

POSTED önbellek bozucularla olma şansı yok


0

ASP.NET MVC kullanıyorsanız, bu satırı denetleyici eyleminin üstüne eklemek yeterlidir:

[OutputCache(NoStore=true, Duration = 0, VaryByParam = "None")]
public ActionResult getSomething()
{

}

Söz konusu davranış tarayıcı tarafındadır; bu cevap sunucu tarafında önbellekleme ile ilgilidir.
Mark Sowul

@MarkSowul Outputcache 3 seçenek İstemci, Sunucu ve herhangi birine sahiptir. IE varsayılan olarak OutputCache kullanır ve bu da çoğunlukla İstemci tarafı önbelleğe alınır. Daha fazla ayrıntıyı burada görebilirsiniz dougwilsonsa.wordpress.com/2011/04/29/…
batmaci

@MarkSowul da ilgili soruyu ve cevabı burada görebilirsiniz. Bunun sunucu tarafında da olduğunu düşünüyor musunuz? stackoverflow.com/questions/2653092/…
batmaci

1
Evet, üzgünüm, haklısın - Cevabınızın hem sunucu tarafı önbelleğini hem de istemci tarafı önbelleğini etkileyebileceğini fark etmedim .
Mark Sowul

-1

IE bu önbelleğe alma hakkına sahiptir; öğenin önbelleğe alınmamasını sağlamak için, başlıklar buna göre ayarlanmalıdır.

ASP.NET MVC kullanıyorsanız ActionFilter; içinde OnResultExecuted, kontrol filterContext.HttpContext.Request.IsAjaxRequest(). Öyleyse, yanıtın sona erme başlığını ayarlayın:filterContext.HttpContext.Response.Expires = -1;

Http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/ uyarınca :

Bazı kişiler, geçerlilik süresi yerine Cache - Control: no - cache üstbilgisini kullanmayı tercih eder. Fark şu:
Cache-Control: no-cache - kesinlikle NO önbellekleme süresi
doluyor: -1 - tarayıcının “genellikle”, koşullu If-Modified-Since isteği aracılığıyla bu sayfaya güncellemeler için Web sunucusuyla iletişim kurar. Ancak, sayfa disk önbelleğinde kalır ve gezinme geçmişine erişmek için GERİ ve İLERİ düğmelerinin kullanılması veya tarayıcının çevrimdışı modda olması gibi uzak Web sunucusuna başvurmadan uygun durumlarda kullanılır.

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.