Кэширование Ajax-запросов
Самый быстрый Ajax-запрос - тот, который не выполняется. Существует два основных способа предотвратить выполнение ненужных запросов:
- На стороне сервера установить HTTP-заголовки так, чтобы обеспечить сохранение ответа в кэше броузера.
- На стороне клиента сохранять полученные данные локально, чтобы потом не пришлось запрашивать их повторно.
Первый прием является наиболее простым в использовании и сопровождении, тогда как второй обеспечивает более точное управление.
Установка HTTP-заголовков
Если необходимо, чтобы броузер кэшировал Ajax-ответы, запросы должны выполняться методом GET. Но простого использования GET-запросов недостаточно; необходимо также, чтобы в ответе присутствовали нужные HTTP-заголовки. Заголовок Expires сообщает броузеру, как долго должен храниться ответ в кэше. Его значением является дата, по истечении которой любые запросы к этому URL-адресу будут направляться не в кэш, а на сервер. Ниже показано, как выглядит заголовок Expires:
Expires: Mon, 28 Jul 23:30:00 GMT
Данный заголовок Expires сообщает броузеру, что этот ответ должен храниться в кэше до июля года. Такие заголовки Expires в далеком будущем удобно использовать для передачи содержимого, которое никогда не изменится, например изображений или статических данных. Дата в заголовке Expires является датой GMT. На языке РНР такой заголовок можно установить следующим способом:
$lifetime = 7 * 24 * 60 * 60; / / 7 дней, в секундах. header('Expires: ' . gmdate(’D, d М Y H:i:s', time() + $lifetime) . ' GMT');
Этот заголовок сообщает броузеру, что он должен хранить данные в кэше 7 дней. Чтобы установить значение заголовка Expires в далеком будущем, нужно указать в переменной $lifetime более длительный интервал. Следующий пример устанавливает заголовок Expires, сообщающий броузеру, что он должен хранить данные 10 лет:
$lifetime = 10 * 365 * 24 * 60 * 60; // 10 лет, в секундах. header('Expires: ' . gmdate(’D, d М Y H:i:s', time() + $lifetime) . ' GMT');
Использование заголовка Expires является самым простым способом обеспечить сохранение Ajax-ответов в кэше броузера.
При этом не придется вносить какие-либо изменения в программный код клиентского сценария и можно продолжать выполнять Ajax-запросы обычным образом, пребывая в уверенности, что броузер будет отправлять запросы на сервер только в случае отсутствия данных в кэше.
Кроме того, поддержку этой оптимизации легко реализовать на стороне сервера, потому что все языки программирования позволяют устанавливать заголовки тем или иным способом. Это самый простой способ обеспечить кэширование данных.
Пример
В действии
html код
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="js/main.js"></script> <style> .status { float: right; color: red; } </style> </head> <body> <div> <button id="get-list">Получить список элементов</button> <span> <label for="cache-id">Запретить кэширование</label> <input id="cache-id" type="checkbox" name="cache" value=""> </span> </div> <span id="status" class="status"></span> <div id="list-wrap" class="list-wrap"></div> </body> </html>
js код
var AJAX_DEMO = (function() { var controls = {}, handlers = { insertContent: function (data) { controls.listWrap.html(data.list); }, buttonClick: function () { var cache = true; if (controls.check.is(':checked')) { cache = false; } $.ajax({ url: 'php/ajax.php', data: 'flag=get', type: 'get', dataType: 'json', cache: cache, success: function (serverAnswer, status, xhr) { if (xhr.status === 200) { handlers.insertContent(serverAnswer); if (!xhr.getResponseHeader('Connection')) { controls.status.html('Данные взяты из кэша'); } else { controls.status.html('Данные получены с сервера'); } } else { alert(xhr.responseText); } }, error: function (xhr) { alert(xhr.responseText); } }); } }, getControls = function () { controls.button = $('#get-list'); controls.listWrap = $('#list-wrap'); controls.status = $('#status'); controls.check = $('#cache-id'); }, addEventList = function () { controls.button.on('click', handlers.buttonClick); }; return { init: function() { $(document).ready(function () { getControls(); addEventList(); }); } }; })(); AJAX_DEMO.init();
php код
$life_time = 7 * 24 * 60 * 60; header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $life_time) . ' GMT'); $json = '{ "list": "
- Элемент списка №1
- Элемент списка №2
- Элемент списка №3
- Элемент списка №4
Для проверки ajax кэширования, можно воспользоваться прилоежнием firebug для FireFox или DevelopmentTools в Chrome (изображение ниже).
Если посмотреть тоже самое в firebug - то увидим что не происходит вообще никаких запросов к серверу.
В случае, если необходимо отменить кэширование, необходимо добавлять к строке запроса случайное значение, или если для ajax запроса используются библиотеки типа JQuery, нужно добавить параметр cache: false, этот параметр включает возможность добавления случайного значения к строке запроса - автоматически.
Сохранение данных локально
Для реализации способа локального хранения данные, можно использовать новшества которые предоставляет HTML5:
- Offline web applications
- Web SQL Database
- IndexedDB
Более детально этот раздел будет рассмотрен в следующих материалах.