Похоже, что если я загружаю динамический контент с помощью $.get(), результат кешируется в браузере.
Добавление случайной строки в QueryString, похоже, решает эту проблему (я использую new Date().toString()), но это похоже на взлом.
Есть ли другой способ добиться этого?
Или, если уникальная строка - единственный способ добиться этого, какие-либо предложения, кроме new Date()?
Вы можете использовать короткое обозначение $.now() вместо того, чтобы каждый раз выполнять (new Date (). GetTime ()).



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


другой способ - не предоставлять заголовки кеша со стороны сервера в коде, который генерирует ответ на вызов ajax:
response.setHeader( "Pragma", "no-cache" );
response.setHeader( "Cache-Control", "no-cache" );
response.setDateHeader( "Expires", 0 );
Неправильно. В IE заголовки без кеширования игнорируются для вызовов XMLHttpRequest, как обсуждается здесь: stackoverflow.com/questions/244918/… DateTime (или мой метод .ajaxSetup) - единственные решения, которые действительно работают.
я только что вставил свою обычную мантру без кеширования, не указано, что это специфично для IE
Это должно отключить кеширование для всех браузеров: response.setHeader ("Cache-Control", "max-age = 0, no-cache, no-store, post-check = 0, pre-check = 0");
Лично я считаю, что метод строки запроса более надежен, чем попытка установить заголовки на сервере - нет гарантии, что прокси или браузер все равно не кэшируют его (некоторые браузеры хуже других - не называют имен).
Обычно я использую Math.random(), но я не вижу ничего плохого в использовании даты (не следует выполнять запросы AJAX достаточно быстро, чтобы дважды получить одно и то же значение).
Объедините Date (). GetTime () вместе с Math.random (), и вы должны быть в безопасности. Кстати, Ext.Ajax также использует getTime (), если указано disableCaching.
Возможно, вам стоит вместо этого взглянуть на $ .ajax () (если вы используете jQuery, как это выглядит). Взгляните на: http://docs.jquery.com/Ajax/jQuery.ajax#options и опцию "cache".
Другой подход - посмотреть, как вы кешируете вещи на стороне сервера.
К сожалению, после некоторого расследования использование $ .ajax () и установка cache = false в основном будет делать то же самое. jQuery добавит случайное число в строку запроса и не проверяет существующую строку запроса. Поэтому я думаю, что будет достаточно использовать $ .get ().
А, ладно. Никогда не пробовал, просто вспомнил, что видел кое-что об этом в документации :)
Даже не обязательно использовать $ .ajax. Просто используйте .ajaxSetup.
Я использую new Date().getTime(), что позволит избежать коллизий, если у вас нет нескольких запросов, выполняемых в течение одной миллисекунды:
$.get('/getdata?_=' + new Date().getTime(), function(data) {
console.info(data);
});
Редактировать: Этому ответу несколько лет. Он по-прежнему работает (значит, я его не удалял), но есть лучшие / более чистые способы достижения этого сейчас. Я предпочитаю метод это, но ответ это также полезен, если вы хотите отключить кеширование для запроса каждый во время жизни страницы.
Я буду отрицать только потому, что это будет проще, если jQuery сделает это, как в ответе Питера Дж. Ваше решение будет работать, но его труднее поддерживать в долгосрочной перспективе.
Какая часть этого требует обслуживания? По сравнению с тем, что делает jQuery?
Возможно, стоит отметить, что код new Date().getTime() используется вот так ... var nocache = new Date().getTime(); var path = 'http://hostname.domain.tld/api/somejsonapi/?cache=' + nocache;. Мне потребовалось несколько минут, чтобы самому понять это. Конечно, ?cache может быть любой формулировкой, которая на самом деле не нужна API.
+1 даже у Ответ Питера Дж. есть лучший подход, этот ответ не является неправильным и плохим. Я считаю, что DV сделаны, потому что ваш выше Питера (как принято). и OP не появляется на SO с начала 2013 года
url = url + (-1 === url.indexOf('?') ? '?' : '&') + "__ = " + Number(new Date());Это единственный способ сработал для меня .. в FF .. Отличная техника. спасибо
@ salamander2007 Это не должен быть общепринятым ответом, cache: false - правильный подход в JQuery.
Небольшое дополнение к приведенным отличным ответам: если вы используете решение для резервного копирования, отличное от ajax, для пользователей без javascript, вам все равно придется исправить эти заголовки на стороне сервера. Это не невозможно, хотя я понимаю тех, кто откажется от этого;)
Я уверен, что есть еще один вопрос по SO, который предоставит вам полный набор подходящих заголовков. Я не совсем убежден, что ответ miceus охватывает все основания на 100%.
Конечно, методы "взлома кеша" выполнят свою работу, но этого не произойдет в первую очередь, если сервер укажет клиенту, что ответ не должен кэшироваться. В некоторых случаях полезно кэшировать ответы, иногда - нет. Пусть сервер определяет правильный срок жизни данных. Возможно, вы захотите изменить его позже. Гораздо проще сделать с сервера, чем из множества разных мест кода пользовательского интерфейса.
Конечно, это не поможет, если у вас нет контроля над сервером.
Как насчет использования запроса POST вместо GET ...? (Что вы должны в любом случае ...)
Я думаю, что это лучшее решение, но, к сожалению, я (каким-то образом) могу выполнить только запрос GET. Итак .. это new Date (). GetTime () на данный момент.
Пожалуйста, добавьте пояснение к своему ответу, чтобы другие могли извлечь из него уроки - Зачем, нужен ли запрос POST?
JQuery $ .get () кэширует результаты. Вместо
$.get("myurl", myCallback)
вы должны использовать $ .ajax, что позволит вам отключить кеширование:
$.ajax({url: "myurl", success: myCallback, cache: false});
+1 Это правильный ответ. Решение Питера J по глобальному отключению кеширования - это плохая практика IMO.
Важно отметить, что это только "глобальный" для страницы / запроса.
+1: кеширование должно зависеть от типа запроса. Некоторым запросам сервера может потребоваться кеширование (где данные сервера статичны), поэтому выбор кеширования на основе запрос по запросу лучше, чем просто выключить все это.
+1 за правильный ответ - предотвращение кеширования для каждого вызова с использованием метода jQuery, а не ручного взлома.
Еще один хороший ответ. Я должен сказать, что для меня в большинстве случаев глобальное отключение кеша было большим преимуществом. Однако все зависит от того, как разработано ваше приложение. Нет серебряной пули, но в этой ситуации я бы порекомендовал функцию, которая принимает логическое значение для кеширования, функцию для обратного вызова и URL-адрес для модульности. Ручной "взлом" - это нормально, но если вы используете jQuery, по возможности придерживайтесь их функций. Это не только упростит разработку сейчас, но и сделает будущие обновления библиотеки.
«$ .Get () JQuery будет кэшировать результаты» не совсем верно; использовать кешированный результат может браузер, а не jQuery. При использовании $.ajax с cache: false jQuery добавляет метку времени к URL-адресу, что обеспечивает свежий ответ от сервера.
Лучший ответ, имо. В качестве примера предположим, что вам нужно сделать серию вызовов ajax для одного и того же URL-адреса (например, соединителя). В большинстве случаев нужно сделать только первую с отключенным кешем.
Следующее предотвратит кэширование всех будущих запросов AJAX, независимо от того, какой метод jQuery вы используете ($ .get, $ .ajax и т. д.)
$.ajaxSetup({ cache: false });
После расследования (Fiddler) похоже, что jQuery реализует это внутренне, просто добавляя временную метку в любом случае (как обсуждается в другом месте в этих ответах). Для меня метод .ajaxSetup чище (на мой взгляд).
Почему это должно быть внутри вызова готовности документа? Как я могу быть уверен, что ни один из моих других обработчиков готовых документов (с вызовами ajax) не сработает раньше этого?
На самом деле это не обязательно должно быть внутри вызова готовности документа.
где нам нужно разместить этот кусок кода? И нужно ли нам размещать это на каждой странице, которая вызывает $ .ajax?
Поместите код так, чтобы он вызывался один раз при загрузке страницы, перед любым вызовом $ .ajax.
Зачем отключать кеширование ajax глобально? Я думаю, что это должно быть сделано для каждого звонка, как то, что делает ответ Джонатана.
Ты прав. Если вы хотите контролировать кеширование для каждого запроса отдельно, а не глобально для всех запросов на странице, дерзайте!
Этот ответ отлично подходит для меня. Но у меня есть одно сомнение, у меня много функций javascript на одной странице jsp, каждая функция будет внутренне вызывать вызов ajax. Так нужно ли мне писать код в вашем ответе во всех функциях?
Нет, один раз при загрузке страницы.
Все, что работает для вашего приложения. Я продолжаю использовать этот метод в коммерческих приложениях, когда мне абсолютно необходимы свежие данные для всех вызовов AJAX. Для других подойдут кэшированные данные.
С одной стороны, Петр прав. С другой стороны, недостатком этого подхода является то, что какой-нибудь младший разработчик или ужасный старший разработчик может в конечном итоге потратить много времени, пытаясь выяснить, почему их вызов кэшируется; и не осознают, что это делается глобально. Очень плохо, они могут в конечном итоге использовать глобальный сеттер для установки другого глобального сеттера, думая, что это способ сделать это. Игра с глобальной переменной похожа на танец газа возле огня.
Объект JQuery AJAX будет следовать перенаправлениям, поэтому даже если вы отключите кеширование глобально, параметр "_ = {timestamp}", который jQuery добавляет для блокировки кеша браузера, может не перенаправляться с перенаправлением. В этом случае ваш запрос все еще может быть кеширован браузером. Решение состоит в том, чтобы либо убедиться, что вместе с перенаправлениями передается специальный параметр, либо вы отключите кеширование в коде на стороне сервера для этих запросов. (Например, gist.github.com/chrisbloom7/…)
Если вы беспокоитесь о влиянии кеширования статического содержимого, jQuery не предотвратит этого, если вы явно не загружаете скрипты и стили через $ .get или тому подобное. Если вы работаете с частичными представлениями, получением ajax и т.п., я настоятельно рекомендую вам реализовать это решение, иначе все может стать волосатым. Я считаю, что проще всего сбросить это на страницу макета / эталона, чтобы не было избыточности.
Наверное, браузер UC не поддерживает эту опцию.
Настоящий вопрос в том, зачем вам это нужно, чтобы это не кешировалось. Если он не должен кэшироваться, потому что он все время изменяется, сервер должен указать, чтобы ресурс не кэшировался. Если он просто иногда меняется (потому что один из ресурсов, от которого он зависит, может измениться), и если у клиентского кода есть способ узнать об этом, он может добавить фиктивный параметр к URL-адресу, который вычисляется из некоторого хэша или даты последнего изменения. этих ресурсов (это то, что мы делаем в ресурсах сценария Microsoft Ajax, чтобы их можно было кэшировать навсегда, но новые версии все еще могут обслуживаться по мере их появления). Если клиент не может знать об изменениях, сервер должен правильно обрабатывать запросы HEAD и сообщать клиенту, использовать ли кешированную версию или нет. Мне кажется, что добавление случайного параметра или указание клиента никогда не кешировать неправильно, потому что кешируемость - это свойство серверного ресурса, и поэтому его следует решать на стороне сервера. Еще один вопрос, который следует задать себе: действительно ли этот ресурс должен обслуживаться через GET или он должен проходить через POST? Это вопрос семантики, но он также имеет последствия для безопасности (есть атаки, которые работают только в том случае, если сервер разрешает GET). POST не будет кэшироваться.
Что делать, если вы используете прокси-серверы, политику кэширования которых вы не контролируете? что, если вашему приложению явно нужно каждый раз выполнять новый запрос? Ответ на вопросы не всегда однозначный, черный и белый, всегда есть серые области.
Правда, не всегда однозначно. Но увидев этот ответ, я усомнился в своих предположениях и помог найти основную причину моей проблемы. Возможно, это не для всех, но мне это помогло. Если вы здесь и читаете это, вам также следует об этом подумать.
Это мне помогло, ResponseCaching по умолчанию был установлен на 60-метровую сторону сервера. Изменил его на No-Cache, и он перестал кэшировать на клиенте.
Если вы используете IE 9, вам необходимо использовать следующее перед определением класса контроллера:
[OutputCache (NoStore = true, Duration = 0, VaryByParam = "*")]
открытый класс TestController: Контроллер
Это предотвратит кеширование браузера.
Подробности по этой ссылке: http://dougwilsonsa.wordpress.com/2011/04/29/disables-ie9-ajax-response-caching-asp-net-mvc-3-jquery/
На самом деле это решило мою проблему.
Для тех из вас, кто использует опцию cache для $.ajaxSetup() в мобильном Safari, кажется, что вам, возможно, придется использовать метку времени для POST, поскольку мобильный Safari также кэширует ее. Согласно документации на $.ajax() (на которую вы перенаправлены с $.ajaxSetup()):
Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_ = {timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET.
Так что установка только этого параметра не поможет вам в случае, о котором я упоминал выше.
Как сказал @Athasach, согласно документации jQuery, $.ajaxSetup({cache:false}) не будет работать для других запросов, кроме GET и HEAD.
В любом случае вам лучше отправить обратно заголовок Cache-Control: no-cache со своего сервера. Это обеспечивает более четкое разделение проблем.
Конечно, это не сработает для URL-адресов служб, которые не принадлежат вашему проекту. В этом случае вы можете рассмотреть возможность проксирования сторонней службы из серверного кода, а не ее вызова из клиентского кода.
добавить Math.random() к URL-адресу запроса
Это даст нестабильные результаты.
Math.random будет действовать только как параметр, например url? _ = [Math.Random ()], он не имеет ничего общего с нестабильным результатом.
Я понимаю, что вы делали. Я просто комментировал, что Math.Random () иногда дает вам одно и то же число дважды. Если вы заполните свою систему неопределенностями, они будут только дополнять друг друга.
По сути, просто добавьте cache:false; в ajax, где, по вашему мнению, содержимое будет меняться по мере продвижения. И место, где контент не изменится, вы можете пропустить это. Таким образом вы будете получать новый ответ каждый раз
Кэширование Ajax в Internet Explorer: что вы собираетесь с этим делать? предлагает три подхода:
- Add a cache busting token to the query string, like ?date=[timestamp]. In jQuery and YUI you can tell them to do this automatically.
- Use POST instead of a GET
- Send a HTTP response header that specifically forbids browsers to cache it
Следуя документации: http://api.jquery.com/jquery.ajax/
вы можете использовать свойство cache с:
$.ajax({
method: "GET",
url: "/Home/AddProduct?",
data: { param1: value1, param2: value2},
cache: false,
success: function (result) {
// TODO
}
});
Если вы используете .net ASP MVC, отключите кеширование действия контроллера, добавив следующий атрибут в функцию конечной точки:
[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]
Вы можете объяснить это дальше? Как этот массив связан с AJAX?
Это не массив, это атрибут в действии контроллера MVC.
Теперь это легко сделать, включив / отключив опцию кеширования в вашем запросе ajax, как это
$(function () {
var url = 'your url goes here';
$('#ajaxButton').click(function (e) {
$.ajax({
url: url,
data: {
test: 'value'
},
cache: true, //cache enabled, false to reverse
complete: doSomething
});
});
});
//ToDo after ajax call finishes
function doSomething(data) {
console.info(data);
}
});
Через 6 лет вы даете такой же ответ, что и Джонатан? ಠ_ಠ
люди могут сказать, что это через 6 лет после публикации вопроса. И мой ответ на этот вопрос отличается от любого другого, не говоря уже о том, что в настоящее время он правильный. Отвечать на такие вопросы не для «спрашивающего», а для сообщества и новичков! В любом случае спасибо за добавление разъяснений!
А какая разница между твоим и этим stackoverflow.com/a/735084/469218?
может это ясность, с точки зрения новичка, задающего такой вопрос !!
Все ответы здесь оставляют след на запрошенном URL-адресе, который будет отображаться в журналах доступа сервера.
Мне нужно было решение на основе заголовков без побочных эффектов, и я обнаружил, что этого можно добиться, настроив заголовки, упомянутые в Как контролировать кеширование веб-страниц во всех браузерах?.
Результат, работающий по крайней мере для Chrome, будет:
$.ajax({
url: url,
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
});Может быть, глупый вопрос, но если мои изображения ajax вернут, будут ли изображения кешироваться? Чтобы избежать массовых запросов Amazon S3?
Марсело Агимовел, я считаю, что это может быть отдельный ТАК вопрос.
добавить заголовок
headers: {
'Cache-Control':'no-cache'
}
Пожалуйста, добавьте пояснения к своему ответу, чтобы другие могли извлечь из него уроки - где следует ли добавлять такие заголовки?
Рассматривали ли вы выбор другого ответа в качестве принятого?