$.getJSON возвращает кешированные данные в IE8

В данный момент я играю с ASP.net MVC и JQuery. Я столкнулся с поведением, которое, кажется, не имеет смысла.

Я вызываю функцию JQuery $.getJSON для заполнения некоторых div. Событие запускается по событию $(document).ready. Это работает отлично.

Существует небольшой AJAX.BeginForm, который добавляет еще одно значение, которое будет использоваться при заполнении div. Он правильно вызывает удаленную функцию и в случае успеха вызывает исходную функцию javascript для повторного заполнения div.

Вот странная часть: в FireFox и Chrome все работает. НО В IE8 (бета-версия) этот второй вызов сценария заполнения Div (который вызывает функцию $.getJSON) получает кэшированные данные и не запрашивает сервер!

Надеюсь, этот вопрос имеет смысл: в двух словах — почему $.getJSON получает кэшированные данные? И почему это влияет только на IE8?


person Andrew Harry    schedule 05.11.2008    source источник
comment
Странно, я вижу этот баг не только в IE, но и в Firefox. Мне помогло отключение кеширования ajax в jquery.   -  person Josef Sábl    schedule 15.09.2010


Ответы (7)


Просто чтобы вы знали, Firefox и Chrome рассматривают все запросы Ajax как некэшируемые. IE (все версии) обрабатывают вызов Ajax так же, как и любой другой веб-запрос. Вот почему вы видите такое поведение.
Как заставить IE загружать данные при каждом запросе:

  • Как вы сказали, используйте опцию «кеш» или «нокэш» в JQuery.
  • Добавляем в запрос случайный параметр (некрасиво, но работает :))
  • На стороне сервера установите кешируемость (например, с помощью атрибута, см. ниже)

Код:

public class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}
person Nico    schedule 05.11.2008
comment
Это решение мне нравится. Мне очень нравится элегантность применения атрибута в MVC. - person Andrew Harry; 06.11.2008
comment
В настоящее время существует OOTB OutputCacheAttribute. - person bzlm; 05.05.2009
comment
@bzlm, но это легче искать - person Simon_Weaver; 25.06.2009
comment
проверьте formatinternet.wordpress.com/2010/01 /14/ для решения на стороне клиента - person Ivo; 22.09.2011
comment
IE снова пытается отличаться от любого другого браузера :-( - person Maksym Kozlenko; 13.04.2012
comment
На самом деле все наоборот, но я согласен как разработчик IE требует терпения :) - person Nico; 22.04.2012
comment
Firefox и Chrome считают все Ajax-запросы некэшируемыми. IE (все версии) обрабатывают Ajax-вызов так же, как и другие веб-запросы - необходима цитата (пожалуйста :)) - person Morgan T.; 01.06.2012
comment
@MorganTiley - прикомандирован. Я не думаю, что это правда. По крайней мере, не в 2012 году. - person Erik Reppen; 27.07.2012

Вот как это сработало для меня...

$.ajaxSetup({ cache: false });
$.getJSON("/MyQueryUrl",function(data,item) {
     // do stuff with callback data
     $.ajaxSetup({ cache: true });
   });
person Jitesh Patil    schedule 11.12.2008
comment
Я боролся с этой проблемой, и ваше решение дало быстрый способ ее решить. :) У меня вопрос, знаете ли вы, какие опции можно использовать для $.ajaxSetup? Документация jQuery, к сожалению, не содержит подробностей... - person Achimnol; 23.07.2009
comment
Доступные параметры идентичны $.ajax. См. docs.jquery.com/Ajax/jQuery. ajax#options для получения дополнительной информации - person Dan Esparza; 12.08.2009
comment
Небольшое предупреждение для приведенного выше кода — он содержит состояние гонки. Поскольку вызов и его ответ асинхронны, вы должны вызывать $.ajaxSetup({ cache: true }); сразу после getJSON(), а не в обратном вызове. - person sax; 10.03.2012

Спасибо, Кент, за ответ. Используя $.ajax('{кеш: нет}'); работал отлично. [редактировать]

Или, по крайней мере, я думал, что сделал. Кажется, что jquery $.getJSON не читает никаких изменений, внесенных в объект $.ajax.

Решение, которое в итоге сработало, состояло в том, чтобы добавить новый параметр вручную.

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

разрешение даты только к минуте; что фактически означает, что это решение по-прежнему кэшируется до одной минуты. Это приемлемо для моих целей.

person Andrew Harry    schedule 05.11.2008
comment
var noCache = новая дата().getTime(); //отдаст вам мс - person scunliffe; 05.11.2008
comment
спасибо Сканлиф! - я новичок в javascript, ASP MVC открыл для меня новые горизонты - person Andrew Harry; 06.11.2008
comment
Вы также можете попробовать что-то вроде Math.Random(). - person Falkayn; 15.09.2009
comment
@Falkayn - можно использовать жесткий Math.Random(), его результаты будут неизвестны, и вы можете получить одно и то же число дважды подряд (или больше). использование new Date().getTime() гарантирует, что это никогда не повторится. (если только вы не можете вернуться в прошлое ;)) - person Rafael Herscovici; 09.01.2013

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

[OutputCache(Duration = 0, VaryByParam = "None")]
person Guy    schedule 13.08.2009
comment
Чудесно! Здорово, что есть альтернативы (я выбрал эту). Спасибо всем участникам! - person Anders Juul; 13.04.2010
comment
Отлично работает с Asp.Net MVC 4.0 - person Mayank; 10.05.2016

Если вы используете 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");
    }
person Josh    schedule 11.05.2009
comment
Хорошая идея — так вы вызываете этот метод расширения на сервере во время обратного вызова, верно? - person Guy; 13.08.2009

Возможно, вам придется отправить блокировщик кеша.

Я бы рекомендовал использовать $.ajax({cache: no}) на всякий случай (добавляет случайный суффикс к запросу на получение)

(В наши дни я обычно использую $.ajax везде, более настраиваемый)

person Kent Fredric    schedule 05.11.2008
comment
Спасибо за ваш ответ! ... я еще не пробовал. Обеспечим обратную связь в ближайшее время - person Andrew Harry; 05.11.2008

Готовы к ответу?

http://lestopher.tumblr.com/post/21742012438/if-youre-using-ie8-and-getjson

Итак, просто добавьте

jQuery.support.cors = true;  

в начале вашего скрипта и BANG это работает!

person stadja    schedule 29.05.2012