$ .getJSON повертає кешовані дані в IE8


102

Я зараз граю з ASP.net MVC та JQuery. Я натрапив на поведінку, яке, здається, не має сенсу.

Я закликаю $.getJSONфункцію JQuery для заповнення деяких дівок. Подія запускається на $(document).readyподію. Це прекрасно працює.

Є невеликий, AJAX.BeginFormякий додає ще одне значення, яке слід використовувати під час заповнення дівок. Він викликає віддалену функцію правильно і при успіху викликає оригінальну функцію javascript для перенаселення дівок.

Ось дивна частина: У FireFox та Chrome - все працює. АЛЕ в IE8 (Beta) цей другий дзвінок до заповненого сценарію Div (який викликає функцію $ .getJSON) отримує кешовані дані та не запитує сервера!

Сподіваюся, що це питання має сенс: У оболонці з гайкою - Чому $.getJSONотримують кешовані дані? І чому він впливає лише на IE8?


Як не дивно, я бачу цю помилку не тільки в IE, але і в Firefox. Відключення кешування ajax у jquery мені допомогло.
Йозеф Сабл

Відповіді:


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
Ендрю Гаррі

1
На сьогодні існує OutputCacheAttribute OOTB.
bzlm

1
@bzlm, але це простіше шукати
Simon_Weaver

перевірити formatinternet.wordpress.com/2010/01/14/… для рішення клієнта
Іво,

1
Насправді, це навпаки, але я згоден, оскільки розробник IE вимагає терпіння :)
Ніко,

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

Дякую Кенту за вашу відповідь. Використання $ .ajax ('{кеш: ні}'); працював на відмінно. [редагувати]

Або, принаймні, я думав, що я. Здається, що jquery $ .getJSON не читає жодних змін, внесених до об’єкта $ .ajax.

Рішення, яке закінчилось, було додати новий параметр вручну

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

дозвіл дати - лише хвилини; що ефективно означає, що це рішення залишається кешованим протягом однієї хвилини. Це прийнятно для моїх цілей.


9
var noCache = нова дата (). getTime (); // передасть вам мс
scunliffe

спасибі, Скунліф! - Я досить новачок у JavaScript, ASP MVC відкрив для мене нові горизонти
Ендрю Гаррі

Ви також можете спробувати щось на зразок Math.Random ().
Фалькайн

@Falkayn - важко Math.Random()використовувати, його результати будуть невідомі, і ви можете отримати те саме число двічі поспіль (або більше). використання new Date().getTime()переконається, що воно ніколи не повторюється. (якщо ви не зможете повернутися назад у часі;))
Дементік

11

Я вирішив цю ж проблему, помістивши в контролер наступний атрибут:

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

Чудово! Чудово мати альтернативи (я вибрав цю). Дякуємо всім учасникам!
Андерс Юль

Чудово працює з 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");
    }

Хороша ідея - ви називаєте цей метод розширення на сервері під час зворотного дзвінка?
Хлопець

2

Можливо, вам доведеться надіслати кеш-вимикач.

Я рекомендую використовувати $ .ajax ({cache: no}) на всякий випадок (додає випадковий суфікс до запиту get)

(Я схильний використовувати $ .ajax скрізь у ці дні, більш настроюваний)


Дякую за вашу відповідь! ... Я ще цього не пробував. Незабаром повернемося
Ендрю Гаррі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.