$ .getJSON mengembalikan data cache di IE8

102

Saya sedang bermain-main dengan ASP.net MVC dan JQuery saat ini. Saya telah menemukan perilaku yang tampaknya tidak masuk akal.

Saya memanggil $.getJSONfungsi JQuery untuk mengisi beberapa div. Acara dipicu pada $(document).readyacara tersebut. Ini bekerja dengan sempurna.

Ada yang kecil AJAX.BeginFormyang menambahkan nilai lain untuk digunakan saat mengisi div. Ini memanggil fungsi jarak jauh dengan benar dan setelah berhasil memanggil fungsi javascript asli untuk mengisi kembali div.

Inilah bagian yang aneh: Di FireFox dan Chrome - Semuanya berfungsi. TAPI Di IE8 (Beta), panggilan kedua ini ke skrip Div populate (yang memanggil fungsi $ .getJSON) mendapat data cache dan tidak meminta server!

Semoga pertanyaan ini masuk akal: Singkatnya - Mengapa $.getJSONmendapatkan data dalam cache? Dan mengapa ini hanya mempengaruhi IE8?

Andrew Harry
sumber
Anehnya, saya melihat bug ini tidak hanya di IE, tapi juga di Firefox. Menonaktifkan ajax caching di jquery membantu saya.
Josef Sábl

Jawaban:

67

Sekadar memberi tahu Anda, Firefox dan Chrome menganggap semua permintaan Ajax sebagai tidak dapat disimpan dalam cache. IE (semua versi) memperlakukan panggilan Ajax seperti permintaan web lainnya. Itulah mengapa Anda melihat perilaku ini.
Cara memaksa IE untuk mengunduh data di setiap permintaan:

  • Seperti yang Anda katakan, gunakan opsi 'cache' atau 'nocache' di JQuery
  • Tambahkan parameter acak ke permintaan (jelek, tapi berfungsi :))
  • Di sisi server, setel kemampuan cache (misalnya menggunakan atribut, lihat di bawah)

Kode:

public class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}
Nico
sumber
1
Solusi ini menarik bagi saya. Saya sangat suka keanggunan menerapkan attibute di MVC
Andrew Harry
1
Ada OOTB OutputCacheAttribute saat ini.
bzlm
1
@bzlm tapi ini lebih mudah untuk dicari
Simon_Weaver
lihat formatinternet.wordpress.com/2010/01/14/… untuk solusi sisi klien
Ivo
1
Sebenarnya sebaliknya, tapi saya setuju sebagai pengembang IE membutuhkan kesabaran :)
Nico
107

Beginilah cara kerjanya untuk saya ...

$.ajaxSetup({ cache: false });
$.getJSON("/MyQueryUrl",function(data,item) {
     // do stuff with callback data
     $.ajaxSetup({ cache: true });
   });
Jitesh Patil
sumber
Saya sedang berjuang dengan masalah ini dan solusi Anda memberikan cara cepat untuk menyelesaikannya. :) Saya punya pertanyaan, apakah Anda tahu opsi apa yang dapat digunakan untuk $ .ajaxSetup? Dokumentasi jQuery sayangnya tidak memberikan rincian ...
Achimnol
1
Opsi yang tersedia identik dengan $ .ajax Lihat docs.jquery.com/Ajax/jQuery.ajax#options untuk informasi lebih lanjut
Dan Esparza
12
Sedikit peringatan untuk kode di atas - ini berisi kondisi balapan. Karena panggilan dan responsnya tidak sinkron, Anda harus menelepon $.ajaxSetup({ cache: true });tepat setelah getJSON()dan bukan di callback.
saksofon
16

Terima kasih Kent atas jawaban Anda. Menggunakan $ .ajax ('{cache: no}'); bekerja dengan sempurna. [edit]

Atau setidaknya saya pikir saya melakukannya. Tampaknya jquery $ .getJSON tidak membaca perubahan apa pun yang dilakukan pada objek $ .ajax.

Solusi yang akhirnya berhasil adalah menambahkan parameter baru secara manual

var noCache = Date();
$.getJSON("/somepage/someaction", { "noCache": noCache }, Callback);

resolusi tanggal hanya dalam hitungan menit; yang secara efektif berarti solusi ini masih menyimpan cache hingga satu menit. Ini dapat diterima untuk tujuan saya.

Andrew Harry
sumber
9
var noCache = Tanggal baru (). getTime (); // akan memberimu ms
scunliffe
terima kasih Scunliffe! - Saya cukup baru mengenal javascript, ASP MVC telah membuka cakrawala baru bagi saya
Andrew Harry
Anda juga dapat mencoba sesuatu seperti Math.Random ().
Falkayn
@ Falkayn - tangguh Math.Random() dapat digunakan, hasilnya tidak akan diketahui dan Anda mungkin mendapatkan nomor yang sama dua kali berturut-turut (atau lebih). menggunakan new Date().getTime()akan memastikan bahwa itu tidak pernah terulang. (kecuali jika Anda dapat kembali ke masa lalu;))
Dementik
11

Saya memecahkan masalah yang sama ini dengan menempatkan atribut berikut pada Action di Controller:

[OutputCache(Duration = 0, VaryByParam = "None")]
Orang
sumber
Hebat! Bagus untuk memiliki alternatif (saya memilih yang ini). Terima kasih untuk semua kontributor!
Anders Juul
Bekerja dengan baik dengan Asp.Net MVC 4.0
Mayank
4

Jika Anda menggunakan ASP.net MVC, pertimbangkan untuk menambahkan metode ekstensi agar mudah menerapkan tanpa caching seperti ini:

    public static void NoCache(this HttpResponse Response)
    {
        Response.Cache.SetNoStore();
        Response.Cache.SetExpires(DateTime.MinValue);
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetValidUntilExpires(false);

        Response.Expires = -1;
        Response.ExpiresAbsolute = DateTime.MinValue;
        Response.AddHeader("Cache-Control", "no-cache");
        Response.AddHeader("Pragma", "no-cache");
    }
Josh
sumber
Ide bagus - jadi Anda memanggil metode ekstensi ini di server selama panggilan balik, kan?
Guy
2

Anda mungkin perlu mengirim pemecah cache.

Saya akan merekomendasikan menggunakan $ .ajax ({cache: no}) untuk berjaga-jaga (menambahkan sufiks acak ke permintaan get)

(Saya cenderung menggunakan $ .ajax di mana-mana akhir-akhir ini, lebih bisa disetel)

Kent Fredric
sumber
Terima kasih atas jawaban Anda! ... Saya belum mencobanya. Akan memberikan umpan balik segera
Andrew Harry