Решение проблемы кэширования $.ajax в Safari на iOS 6

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

JS
Скопировать код
$.ajaxSetup({ cache: false }); // Вот решение! Глобально отключаем кэширование.

Установив cache: false глобально, мы предотвращаем натуральную тенденцию Safari в iOS 6 к кэшированию AJAX-запросов, освобождаясь от требования делать это для каждого отдельного вызова. Таким образом, мы гарантируем, что данные с сервера всегда будут свежими.

Кинга Идем в IT: пошаговый план для смены профессии

Почему Safari на iOS 6 так же упорно кеширует данные?

В Safari на iOS 6 используется WebKit, который зачастую сохраняет результаты POST-запросов в кэше. Согласно стандартам HTTP, это допускается, если заголовок Cache-Control не предписывает иного. Для предотвращения нежелательного кэширования можно воспользоваться следующими методами:

  1. Использовать заголовок Cache-Control: no-cache в ответах AJAX.
  2. Присвоить уникальную метку времени каждому запросу.
  3. Настроить сервер Apache таким образом, чтобы он добавлял заголовки Cache-Control для POST-запросов.

Как же настроить сервер?

Поручим эту задачу Apache

Apache может облегчить вам эту задачу: достаточно внести следующие изменения в файл конфигурации:

apacheconf
Скопировать код
<FilesMatch "\.(php|cgi|pl)$">
    Header set Cache-Control "no-cache" // Так каждый POST-запрос будет автоматически отмечен как "не подлежащий кэшированию"!
</FilesMatch>

Усильте защиту добавлением дополнительных заголовков

Не будет лишним добавить заголовок, который будет служить дополнительной защитой от кэширования:

http
Скопировать код
Pragma: no-cache // Дополнительная мера, позволяющая надежно предотвратить кэширование

По аналогии с HDR на вашем iPhone, это предоставляет дополнительный уровень защиты от нежелательного кэширования.

Когда статические API отказываются кэшировать

Статические API обязаны всегда устанавливать cacheability в NoCache. Кэширование их ответов под строгим запретом!

Я — клиентский скрипт. Что я могу сделать?

Трюк с меткой времени

Вы можете добавить метку времени к URL запроса с использованием функции getTime() в JavaScript:

JS
Скопировать код
function noCacheUrl(url) {
    return url + (url.includes('?') ? '&' : '?') + 'timestamp=' + new Date().getTime()); // Так URL становится уникальным при каждом запросе
}

Автоматическое добавление метки времени в AJAX-запросы

jQuery.ajaxPrefilter позволяет ненавязчиво вставлять метку времени:

JS
Скопировать код
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    if (originalOptions.type.toUpperCase() === "POST") {
        options.url = noCacheUrl(originalOptions.url); // Каждый POST-запрос будет содержать уникальную метку времени
    }
});

Глобальное управление кэшом с помощью $.ajaxSetup. Действуйте как настоящий профессионал!

Установите управление кэшом для всех AJAX-запросов так, чтобы было ясно, кто здесь главный:

JS
Скопировать код
$.ajaxSetup({
    beforeSend: function(jqXHR) {
        jqXHR.setRequestHeader("Cache-Control", "no-cache"); // Сказали кэшу "нет"
        jqXHR.setRequestHeader("Pragma", "no-cache"); // На всякий случай усилили наше отрицание
    }
});

Небольшой экскурс: время для иллюстрации!

Сформулируем задачу в других терминах: представим, что Safari на iOS 6 – это библиотекарь (👩‍🏫), который сортирует книги (📚 = запросы). Когда книга возвращается, библиотекарь расставляет ее на полку "Вот что вы читали на прошлой неделе" или просто "Кэш". Чтобы каждый раз получать "новую книгу", мы снабжаем каждый запрос уникальной "закладкой" (🔖 = метка времени).

Стратегии против кэширования для кофе-брейка

Тук-тук! Привет, нежелательное кэширование.

Очень важно, чтобы все разработчики были в курсе особенностей кэширования в Safari на iOS 6. Они не умеют читать мысли, поэтому лучше заранее подстраховаться от возможных проблем.

Не используете jQuery? Не проблема!

Если вы предпочитаете работать без jQuery, то использование XMLHttpRequest или других библиотек позволит вам эффективно избегать "ледяных островов" кэширования.

Оптимизируйте свою стратегию управления кэшем

От изменения типов запросов до доработки ответов сервера: убедитесь, что ваша стратегия управления кэшем эффективна и грамотно продумана.

Домашняя работа!

Старайтесь следить за обновлениями в документации jQuery и продолжайте изучение других библиотек. Это позволит вам глубже понять тонкости работы с кэшированием.