$ .getJSON ส่งคืนข้อมูลแคชใน IE8


102

ฉันกำลังเล่นกับ ASP.net MVC และ JQuery ในขณะนี้ ฉันเจอพฤติกรรมที่ดูเหมือนจะไม่สมเหตุสมผล

ฉันกำลังเรียก$.getJSONใช้ฟังก์ชันของ JQuery เพื่อเติมข้อมูลของ div เหตุการณ์ถูกทริกเกอร์ใน$(document).readyเหตุการณ์ นี้ทำงานได้อย่างสมบูรณ์

มีขนาดเล็กAJAX.BeginFormซึ่งจะเพิ่มค่าอื่นที่จะใช้เมื่อเติมข้อมูล div เรียกใช้ฟังก์ชันระยะไกลอย่างถูกต้องและเมื่อประสบความสำเร็จเรียกฟังก์ชันจาวาสคริปต์ดั้งเดิมเพื่อสร้าง divs ใหม่

นี่คือส่วนที่แปลก: ใน FireFox และ Chrome - ทุกอย่างใช้งานได้ แต่ใน IE8 (เบต้า) การเรียกครั้งที่สองนี้เพื่อเติมสคริปต์ Div (ซึ่งเรียกฟังก์ชัน $ .getJSON) ได้รับข้อมูลแคชและไม่ถามเซิร์ฟเวอร์!

หวังว่าคำถามนี้จะสมเหตุสมผล: ในเปลือกถั่ว - เหตุใดจึง$.getJSONได้รับข้อมูลแคช แล้วทำไมมันถึงมีผลกับ IE8 เท่านั้น?


น่าแปลกที่ฉันเห็นข้อผิดพลาดนี้ไม่เพียง แต่ใน IE แต่ใน Firefox ด้วย การปิดใช้งานการแคช ajax ใน jquery ช่วยฉันได้
Josef Sábl

คำตอบ:


67

เพื่อแจ้งให้คุณทราบ Firefox และ Chrome ถือว่าคำขอ Ajax ทั้งหมดไม่สามารถเข้าถึงได้ IE (ทุกเวอร์ชัน) ถือว่าการโทร Ajax เหมือนกับคำขอเว็บอื่น ๆ นั่นเป็นเหตุผลที่คุณเห็นพฤติกรรมนี้
วิธีบังคับให้ IE ดาวน์โหลดข้อมูลตามคำขอแต่ละครั้ง:

  • อย่างที่คุณพูดให้ใช้ตัวเลือก 'แคช' หรือ 'nocache' ใน JQuery
  • เพิ่มพารามิเตอร์แบบสุ่มในคำขอ (น่าเกลียด แต่ใช้งานได้ :))
  • ที่ฝั่งเซิร์ฟเวอร์ตั้งค่าความสามารถในการใช้งานได้ (ตัวอย่างเช่นการใช้แอตทริบิวต์ดูด้านล่าง)

รหัส:

public class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}

1
โซลูชันนี้เหมาะสำหรับฉัน ฉันชอบความสง่างามของการใช้เครื่องแต่งกายใน MVC
Andrew Harry

1
ปัจจุบันมี OutputCacheAttribute OOTB
bzlm

1
@bzlm แต่ค้นหาได้ง่ายกว่า
Simon_Weaver

ตรวจสอบformatinternet.wordpress.com/2010/01/14/…สำหรับโซลูชันฝั่งไคลเอ็นต์
Ivo

1
อันที่จริงมันเป็นอีกทางหนึ่ง แต่ฉันยอมรับในฐานะผู้พัฒนา IE ต้องใช้ความอดทน :)
Nico

107

นี่คือวิธีการทำงานสำหรับฉัน ...

$.ajaxSetup({ cache: false });
$.getJSON("/MyQueryUrl",function(data,item) {
     // do stuff with callback data
     $.ajaxSetup({ cache: true });
   });

ฉันกำลังดิ้นรนกับปัญหานี้และวิธีแก้ปัญหาของคุณมีวิธีแก้ปัญหาอย่างรวดเร็ว :) ฉันมีคำถามคุณรู้หรือไม่ว่าตัวเลือกใดที่สามารถใช้กับ $ .ajaxSetup ได้? เอกสาร jQuery ไม่ได้ให้รายละเอียดน่าเสียดาย ...
Achimnol

1
ตัวเลือกที่มีจะเหมือนกับ $ .ajaxดูdocs.jquery.com/Ajax/jQuery.ajax#optionsสำหรับข้อมูลเพิ่มเติม
Dan Esparza

12
คำเตือนเล็กน้อยสำหรับโค้ดด้านบน - มีเงื่อนไขการแข่งขัน เนื่องจากการโทรและการตอบกลับเป็นแบบอะซิงโครนัสคุณควรโทร$.ajaxSetup({ cache: true });ทันที getJSON()และไม่อยู่ในการโทรกลับ
sax

16

ขอบคุณ Kent สำหรับคำตอบของคุณ ใช้ $ .ajax ('{cache: no}'); ทำงานได้อย่างสมบูรณ์แบบ [แก้ไข]

หรืออย่างน้อยฉันก็คิดว่าฉันทำ ดูเหมือนว่า jquery $ .getJSON ไม่ได้อ่านการเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นกับวัตถุ $ .ajax

วิธีแก้ปัญหาที่ได้ผลคือการเพิ่มพารามิเตอร์ใหม่ด้วยตนเอง

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

ความละเอียดวันที่เป็นเพียงนาที ซึ่งหมายความว่าโซลูชันนี้ยังคงแคชได้นานถึงหนึ่งนาที นี่เป็นที่ยอมรับสำหรับวัตถุประสงค์ของฉัน


9
var noCache = วันที่ใหม่ (). getTime (); // จะให้คุณกับ ms
scunliffe

ขอบคุณ Scunliffe! - ฉันค่อนข้างใหม่กับจาวาสคริปต์ ASP MVC ได้เปิดโลกทัศน์ใหม่ให้ฉัน
Andrew Harry

คุณยังสามารถลองทำสิ่งต่างๆเช่น Math.Random ()
Falkayn

@Falkayn - Math.Random()สามารถใช้งานได้ยากผลลัพธ์จะไม่เป็นที่รู้จักและคุณอาจได้รับหมายเลขเดียวกันสองครั้งติดต่อกัน (หรือมากกว่า) การใช้new Date().getTime()จะทำให้แน่ใจว่าจะไม่ทำซ้ำ (เว้นแต่คุณจะสามารถย้อนเวลากลับไปได้))
Rafael Herscovici

11

ฉันแก้ไขปัญหาเดียวกันนี้โดยวางแอตทริบิวต์ต่อไปนี้ใน Action ใน Controller:

[OutputCache(Duration = 0, VaryByParam = "None")]

วิเศษมาก! เยี่ยมมากที่มีทางเลือกอื่น (ฉันเลือกอันนี้) ขอบคุณผู้ร่วมให้ข้อมูลทุกคน!
Anders Juul

ใช้ได้ดีกับ Asp.Net MVC 4.0
Mayank

4

หากคุณกำลังใช้ ASP.net MVC ให้ลองเพิ่มวิธีการขยายเพื่อให้ใช้งานได้อย่างง่ายดายโดยไม่ต้องแคช:

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

ความคิดที่ดี - คุณจึงเรียกวิธีการขยายนี้บนเซิร์ฟเวอร์ระหว่างการโทรกลับใช่ไหม
Guy

2

คุณอาจต้องส่งแคชเบรกเกอร์

ฉันอยากจะแนะนำให้ใช้ $ .ajax ({cache: no}) ในกรณีนี้ (เพิ่มคำต่อท้ายแบบสุ่มในคำขอรับ)

(ฉันมักจะใช้ $ .ajax ทุกที่ทุกวันนี้ปรับแต่งได้มากกว่า)


ขอบคุณสำหรับคำตอบ! ... ฉันยังไม่ได้ลอง จะให้ฟีดกลับในไม่ช้า
Andrew Harry

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.