Grails: лучший способ отправлять заголовки кеша при каждом вызове ajax - PullRequest
12 голосов
/ 14 мая 2011

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

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

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

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

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

Спасибо!

Ответы [ 2 ]

19 голосов
/ 14 мая 2011

Вот что я наконец понял.Большинство библиотек 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:заголовок без кэша вместо срока действия.Вот разница:

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

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

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

2 голосов
/ 14 мая 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...