Неожиданное кэширование результатов AJAX в IE8

128

У меня возникла серьезная проблема с результатами кэширования Internet Explorer из запроса JQuery Ajax.

У меня есть заголовок на моей веб-странице, который обновляется каждый раз, когда пользователь переходит на новую страницу. После загрузки страницы я делаю это

$.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");

Он просто вводит информацию заголовка на страницу. Вы можете проверить это, перейдя в www.wikipediamaze.com, а затем войдите в систему и запустите новую головоломку.

В каждом браузере, который я тестировал (Google Chrome, Firefox, Safari, Internet Explorer), он отлично работает кроме в IE. Eveything впрыскивается в IE только в первый раз, но после этого он даже не делает вызов /game/getpuzzleinfo. Как будто он кэшировал результаты или что-то в этом роде.

Если я сменил вызов на $.post("/game/getpuzzleinfo", ..., IE забирает его просто отлично. Но затем Firefox перестает работать.

Может кто-то пролить свет на это, почему IE кэширует мои призывы $.get ajax?

UPDATE

В соответствии с предложением ниже, я изменил свой запрос ajax на этот вопрос, который исправил мою проблему:

$.ajax({
    type: "GET",
    url: "/game/getpuzzleinfo",
    dataType: "json",
    cache: false,
    success: function(data) { ... }
});
  • 8
    Спасибо, что спросили это. Я потерял дар речи, что это поведение браузера.
  • 1
    Хороший вопрос и действительно классный сайт. Отличная идея.
Показать ещё 1 комментарий
Теги:
internet-explorer

10 ответов

176
Лучший ответ

IE печально известен своим агрессивным кэшированием ответов Ajax. Когда вы используете jQuery, вы можете установить глобальный параметр:

$.ajaxSetup({
    cache: false
});

что приведет к тому, что jQuery будет добавлять случайное значение в строку запроса запроса, тем самым предотвращая кэширование ответа IE.

Обратите внимание, что если у вас есть другие вызовы Ajax, когда вы хотите кэшировать, это также отключит их для них. В этом случае переключитесь на использование метода $.ajax() и включите этот параметр явно для необходимых запросов.

Подробнее см. http://docs.jquery.com/Ajax/jQuery.ajaxSetup.

  • 1
    Вы также можете добавить отметку времени в конце ваших URL. Не уверен, почему jQuery не использует этот подход.
  • 14
    @Eric: это то, что делает jQuery внутри - опция «cache: false» просто говорит ему сделать это.
Показать ещё 3 комментария
8

Как упоминалось marr75, GET кэшируются.

Есть несколько способов борьбы с этим. Помимо изменения заголовка ответа, вы также можете добавить произвольную строку строки запроса в конец целевого URL. Таким образом, IE будет думать, что это разные URL-адреса при каждом запросе.

Существует несколько способов сделать это (например, использование Math.random(), изменение даты и т.д.).

Здесь один из способов сделать это:

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

Получает всегда кешируемость. Одна из стратегий, которая может работать, - отредактировать заголовок ответа и сообщить клиенту, что он не кэширует информацию или не истекает срок действия кэша.

  • 0
    Это звучит как хорошая идея. Как бы я поступил так?
  • 1
    Это загруженный вопрос, зависит от вашего кода на стороне сервера. Посмотрите запись в Википедии "Список заголовков HTTP" для небольшого руководства. Примеры: Cache-Control: no-cache Срок действия истекает: четверг, 01 декабря 1994 16:00:00 GMT Обычно вам нужно добавить эти заголовки ответа в ваш http-ответ. Это довольно просто в ASP.NET, Ruby и PHP. Просто найдите язык на стороне сервера, который вы используете + измените заголовки ответа.
Показать ещё 1 комментарий
2

Если вы вызываете страницу ashx, вы также можете отключить кеширование на сервере со следующим кодом:

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

NickFitz дает хороший ответ, но вам нужно также отключить кеширование в IE9. Чтобы ориентироваться только на IE8 и IE9, вы можете сделать это:

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

это то, что я делаю для вызовов ajax:

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

он работает очень хорошо для меня.

0

Если вы используете ASP.NET MVC, достаточно добавить эту строку поверх действия контроллера:

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

}
  • 0
    Поведение в вопросе на стороне браузера; Этот ответ относится к кешированию на стороне сервера.
  • 0
    @MarkSowul Outputcache имеет 3 варианта клиента, сервера и любой. IE использует OutputCache по умолчанию любой, который идет в основном как кэширование на стороне клиента. Вы можете увидеть более подробную информацию здесь dougwilsonsa.wordpress.com/2011/04/29/…
Показать ещё 2 комментария
0

Просто написал блог по этой точной проблеме только с помощью ExtJS (http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html )

Проблема заключалась в том, что я использовал специальный формат перезаписи URL-адресов. Я не мог использовать обычные параметры строки запроса (? param = value), поэтому я написал параметр busting для кэша как опубликованную переменную..... я подумал бы, что использование POST-переменных немного безопаснее, чем GET, просто потому, что множество фреймворков MVC используют шаблон

Протокол://хост/контроллер/действие/param1/param2

и поэтому отображение значения переменной в значение теряется, а параметры просто сложены... поэтому при использовании параметра кэша кэша GET

то есть. Протокол://хост/контроллер/действие/param1/param2/no_cache122300201

no_cache122300201 можно ошибочно принять за параметр $param3, который может иметь значение по умолчанию

то есть.

действие публичной функции ($ param1, $param2, $param3 = "значение по умолчанию" ) { //..// }

нет шансов на то, что это произойдет с кластерами POSTED

0

Ответы здесь очень полезны для тех, кто использует jQuery или по какой-либо причине напрямую использует объект xmlHttpRequest...

Если вы используете автоматически созданный прокси-сервер Microsoft, его не так просто решить.

Хитрость заключается в использовании метода Sys.Net.WebRequestManager.add_invokingRequest в обработчике события, изменяющего URL-адрес запроса:

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

Я написал об этом в блоге: http://yoavniran.wordpress.com/2010/04/27/ie-caching-ajax-results-how-to-fix/

-1

IE находится в пределах своих прав на выполнение этого кэширования; чтобы гарантировать, что элемент не кэширован, заголовки должны быть установлены соответствующим образом.

Если вы используете ASP.NET MVC, вы можете написать ActionFilter; в OnResultExecuted, проверьте filterContext.HttpContext.Request.IsAjaxRequest(). Если это так, установите заголовок для ответа на ответ: filterContext.HttpContext.Response.Expires = -1;

По http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/:

Некоторые люди предпочитают использовать заголовок Cache-Control: no-cache а не истекает. Вот разница:
Cache-Control: no-cache - абсолютно без кэширования
Истекает: -1 - браузер "обычно" связывается с Веб-сервер для обновления этой страницы с помощью условного If-Modified-Since запрос. Однако страница остается в кеше диска и используется в соответствующих ситуациях без контакта с пультом дистанционного управления Веб-сервер, например, когда кнопки BACK и FORWARD используются для доступ к истории навигации или когда браузер находится в автономном режиме.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню