Подтвердить что ты не робот

Grails: лучший способ отправить заголовки кешей с каждым вызовом ajax

Хорошо известно, что Internet Explorer агрессивно кэширует аякс-вызовы, тогда как все остальные браузеры каждый день захватывают данные. Обычно это плохо: я никогда не встречал случая, когда я хочу, чтобы ajax НЕ обращался к серверу. Firefox, Safari и другие браузеры знают это и не кэшируют вызовы ajax.

Чтобы предотвратить кеширование IE, вам необходимо выполнить одно из следующих действий:

  • добавить маркер кэш-строки в строку запроса (например, ?time=[timestamp])
  • отправить заголовок ответа HTTP, который специально запрещает IE кэшировать запрос
  • используйте ajax POST вместо GET

Я предпочитаю устанавливать заголовок без кэша. Это правильный способ: он говорит, что все браузеры не кэшируют, что именно вы намерены. Метод строки запроса заполняет кеш браузера материалами, которые никогда не будут восстановлены, что оставляет меньше места для законного содержимого кеша. И метод POST - это повреждение HTTP: POST предназначены для изменения данных.

В Grails лучший способ автоматической отправки заголовка do-not-cache для всех запросов ajax? Я не хочу изменять какие-либо контроллеры, поэтому я думаю, что там должен быть крутой фильтр-трюк или что-то в этом роде.

Спасибо!

4b9b3361

Ответ 1

Вот что я, наконец, понял. Большинство javascript-библиотек, включая jQuery, YUI, Mootools и Prototype, отправляют заголовок X-Requested-With: XmlHttpRequest для каждого запроса ajax.

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

Ниже приведен фильтр Grails, который предотвращает кэширование ajax-запросов, которые идентифицируют себя с заголовком X-Requested-With: XmlHttpRequest:

// put this class in grails-app/config/
class AjaxFilters {
    def filters = {
        all(controller:'*', action:'*') {
            before = {
                if (request.getHeader('X-Requested-With')?.equals('XMLHttpRequest')) {
                    response.setHeader('Expires', '-1')
                }
            }
        }
    }
}

Некоторые люди предпочитают использовать заголовок Cache-Control: no-cache вместо истечения срока действия. Здесь разница:

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

Добавив этот фильтр, вы делаете кеширование Internet Explorer совместимым с тем, что уже делают Firefox и Safari.

Кстати, я столкнулся с проблемой кэширования в IE8 и IE9. Я предполагаю, что проблема существует и для IE7 и IE6.

Ответ 2

Мы используем jQuery для всех вызовов ajax, поэтому добавляем этот блок к нашему main.gsp(макет верхнего уровня):

<g:javascript>
  jQuery(document).ready(function() {
    $.ajaxSetup({
      cache:false
    });
  });
</g:javascript>

Также ответил здесь