Несподіване кешування AJAX призводить до IE8


135

У мене є серйозна проблема з результатами кешування 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?

ОНОВЛЕННЯ

Відповідно до запропонованої нижче пропозиції, я змінив запит на ajax на це, що вирішило мою проблему:

$.ajax({
    type: "GET",
    url: "/game/getpuzzleinfo",
    dataType: "json",
    cache: false,
    success: function(data) { ... }
});

8
Дякую за запитання. Я мовчу, що ця поведінка браузера.
jjohn

1
Хороше запитання та дуже класний веб-сайт. Гарна ідея.
MikeMurko

Відповіді:


177

IE відомий своїм агресивним кешуванням відповідей Ajax. Використовуючи jQuery, ви можете встановити глобальний варіант:

$.ajaxSetup({
    cache: false
});

що призведе до того, що jQuery додасть випадкове значення до рядка запиту запиту, тим самим запобігаючи IE кешування відповіді.

Зауважте, що якщо у вас є інші дзвінки Ajax, які ви хочете кешувати, це також вимкне їх. У цьому випадку перейдіть до використання методу $ .ajax () і ввімкніть цю опцію для явних запитів.

Докладнішу інформацію див. У розділі http://docs.jquery.com/Ajax/jQuery.ajaxSetup .


1
Ви також можете додати часову позначку до кінця своїх URL-адрес. Не впевнений, чому jQuery замість цього не підходить.
Ерік Джонсон

14
@Eric: саме це jQuery робить внутрішньо - опція "кеш: помилка" просто говорить про це.
NickFitz

Чому у jquery за умовчанням це не ввімкнено?
швидкісний літак

Щойно я помітив, що параметри кешу не працюють, коли ви намагаєтесь запитувати домашню сторінку в IE 8, із закликом до /. Змініть його на /index.phpбудь-яку повну URL-адресу. Або додайте самі підроблені /?f=f
парами на

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

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


Це звучить як гарна ідея. Як би я пішов робити це?
Міхей

1
Це завантажене питання, залежить від коду вашого сервера. Див. Запис у Вікіпедії "Список заголовків HTTP" для отримання невеликих вказівок. Приклади: Кеш-контроль: без кешу Закінчується: Чт, 01 грудня 1994 16:00:00 GMT В основному вам потрібно додати ці заголовки відповідей до вашого http відповіді. Досить просто в ASP.NET, Ruby та PHP. Просто знайдіть мову сторони сервера, яку ви використовуєте + змінити заголовки відповідей.
marr75

3
Крім того, і це зовсім не критика Jquery (я люблю цю бібліотеку), метод додавання параметру випадкового рядка запиту безпечний, але неввічливий для клієнта (він може залишити їх утримувати елементи в кеші, які ніколи не будуть використовуватися знову).
marr75

2

Якщо ви телефонуєте на сторінку ashx, ви також можете відключити кешування на сервері за допомогою наступного коду:

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

1

це те, що я роблю для дзвінків Ajax:

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

це працює досить добре для мене.


1

NickFitz дає хорошу відповідь, але вам потрібно буде також вимкнути кешування в IE9. Щоб націлити на лише IE8 та IE9, ви могли це зробити;

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

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/


0

Щойно написав блог щодо цієї точної проблеми лише за допомогою ExtJS ( http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html )

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

протокол: // хост / контролер / дія / param1 / param2

і тому зіставлення відображення імені змінної у значення втрачається, а парами просто укладаються ... так що при використанні параметра GET кеш-пам'яті GET

тобто протокол: // хост / контролер / дія / param1 / param2 / no_cache122300201

no_cache122300201 можна помилити параметр $ param3, який може мати значення за замовчуванням

тобто

дія публічної функції ($ param1, $ param2, $ param3 = "значення за замовчуванням") {//..//}

немає шансів, що це станеться з POSTED кестерами


0

Якщо ви використовуєте ASP.NET MVC, досить додати цей рядок поверх дії контролера:

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

}

Поведінка, про яку йдеться, перебуває на стороні браузера; ця відповідь стосується кешування на стороні сервера.
Марк Совул

@MarkSowul Outputcache має 3 варіанти клієнта, сервера та будь-якого. IE використовує OutputCache за замовчуванням будь-який, який в основному використовується як кешування на стороні клієнта. Ви можете ознайомитись з детальніше тут dougwilsonsa.wordpress.com/2011/04/29/…
batmaci

@MarkSowul Ви також можете побачити відповідне питання та відповідь тут. Як ви думаєте, це також на стороні сервера? stackoverflow.com/questions/2653092 / ...
batmaci

1
Так, вибачте, ти маєш рацію - я не розумів, що твоя відповідь може вплинути як на кеш на стороні сервера, так і на кеш на стороні клієнта.
Марк Совул

-1

IE в межах своїх прав робити це кешування; щоб елемент не був кешований, заголовки повинні бути встановлені відповідно.

Якщо ви використовуєте ASP.NET MVC, ви можете написати an ActionFilter; в OnResultExecuted, перевірити filterContext.HttpContext.Request.IsAjaxRequest(). Якщо так, встановіть заголовок терміну дії відповіді:filterContext.HttpContext.Response.Expires = -1;

Відповідно до http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/ :

Деякі люди вважають за краще використовувати кеш-керування: ні - заголовок кешу замість закінчується. Ось відмінність:
Кеш-контроль: без кешу - абсолютно НЕ кешування
Закінчується: -1 - браузер "зазвичай" контактує з веб-сервером для оновлень на цій сторінці за допомогою умовного запиту If-Modified-Since. Однак сторінка залишається в кеш-диску диска і використовується у відповідних ситуаціях без контакту з віддаленим веб-сервером, наприклад, коли кнопки BACK і FORWARD використовуються для доступу до історії навігації або коли браузер перебуває в автономному режимі.

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