Механизм работы Application Cache прост. Когда пользователь первый раз пользуется сайтом, страницы запоминаются в кэше браузера. Затем при последующих посещениях, а также когда соединение с Интернет теряется, используются заранее сохраненные данные в специальном «хранилище». Контроль над кэшированием сайта производится с помощью специального файла, названного manifest.

«Хранилище» - условное название, используемое в браузерах для обозначения места хранения Application Cache. Механизмы работы Application Cache и стандартного кэша браузера различны, поэтому требуют отдельного размещения. Отличия механизмов работы между двумя видами кэширования следующие:

  • Данные помещённые в стандартный кэш могут быть автоматически, без команды со стороны пользователя или сервера, удаленны при его заполнении или истечения стока действия, указанного в заголовках файлов. Данные помещённые в хранилище Application Cache могут быть удалены только по команде пользователя или сервера.
  • В стандартный кэш попадают только файлы, загруженные в процессе просмотра страницы. В Application Cache можно поместить любые файлы, загружаемые с сервера согласно инструкции manifest.

Использование кэш-интерфейса дает приложению три преимущества:

  • поиск в режиме офлайн – пользователи могут просматривать весь сайт в режиме офлайн;
  • скорость – ресурсы кэшируются локально, поэтому быстрее загружаются;
  • уменьшение нагрузки на сервер – браузер загружает только измененные ресурсы.

Файл манифеста кэша

Файл манифеста кэша представляет собой простой текстовый файл со списком ресурсов, которые браузер должен кэшировать для доступа в автономном режиме.

Обращение к файлу манифеста

Чтобы разрешить кэширование приложения, включите атрибут manifest в тег html документа:

<html manifest="example.appcache">
...
</html>

Атрибут manifest должен присутствовать на каждой странице веб-приложения, которое нужно кэшировать. Браузер не кэширует страницу, если она не содержит атрибут manifest или не указана в самом файле манифеста. Это означает, что любая страница с атрибутом manifest, которую посетит пользователь, будет неявным образом добавлена в кэш приложения. Таким образом, перечислять в манифесте все страницы не нужно.

Атрибут manifest может указывать на абсолютный URL или относительный путь, но абсолютный URL должен находиться в том же домене, что и веб-приложение. Файл манифеста может иметь любое расширение, но его MIME-тип должен быть правильным.

<html manifest="http://www.example.com/example.mf">
...
</html>

В качестве MIME-типа для файла манифеста необходимо указывать значение text/cache-manifest. Возможно, в конфигурацию веб-сервера или файл .htaccess придется добавить пользовательский тип файла. Например, чтобы настроить этот MIME-тип в Apache, добавьте в файл конфигурации следующую строку:

AddType text/cache-manifest .appcache

Структура файла манифеста

Простой файл манифеста может выглядеть примерно так:

CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js

В этом примере кэшируются четыре файла на странице, которая указывает на данный файл манифеста.

Необходимо отметить несколько моментов.

  • Строка CACHE MANIFEST является обязательной и должна быть первой.
  • Объем кэшированных данных для сайтов не может превышать 5 МБ. При написании приложений для Интернет-магазина Chrome это ограничение можно снять с помощью атрибута unlimitedStorage.
  • Если файл манифеста или указанный в нем ресурс загрузить не удается, кэш не обновляется. В этом случае браузер продолжает использовать старый кэш приложения.

Рассмотрим более сложный пример.

CACHE MANIFEST
# 2018-03-01:v1

# Explicitly cached 'master entries'.
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js

# Resources that require the user to be online.
NETWORK:
login.php
/myapi
http://api.twitter.com

# static.html will be served if main.py is inaccessible
# offline.jpg will be served in place of all images in images/large/
# offline.html will be served in place of all other .html files
FALLBACK:
/main.py /static.html
images/large/ images/offline.jpg
*.html /offline.html

Строки, которые начинаются с символа #, являются комментариями, но могут служить и для другой цели. Кэш приложения обновляется только при изменении файла манифеста. Это означает, что, например, изменения, внесенные в графический ресурс или функцию JavaScript, повторно не кэшируются. Для обновления кэшированных файлов необходимо отредактировать сам файл манифеста. Чтобы у пользователей всегда была последняя версия приложения, можно создать строку комментария с номером версии, хэш-суммой файлов или датой. С появлением новой версии кэша можно обновлять и программными средствами, как описано в разделе Обновление кэша.

Манифест может содержать три раздела: CACHE, NETWORK и FALLBACK.

CACHE

Это раздел для записей по умолчанию. Файлы, указанные здесь (или сразу после атрибута CACHE MANIFEST), будут кэшироваться при первой же загрузке.

NETWORK

Файлы, указанные в этом разделе, представляют собой надежные ресурсы, которым необходимо подключение к серверу. Все запросы к ним идут в обход кэша, даже если пользователь находится в режиме офлайн. Здесь можно использовать знаки подстановки.

FALLBACK

Дополнительный раздел, содержащий резервные страницы на случай, если ресурс недоступен. Первый URL указывает ресурс, а второй – его резервную страницу. Оба адреса должны быть относительными и находиться в том же домене, что и файл манифеста. Здесь можно использовать знаки подстановки.

Примечание. Разделы могут быть указаны в любом порядке, и каждый из них может встречаться в одном манифесте несколько раз.

Обновление кэша

Офлайн-приложение хранится в кэше, пока не произойдет одно из перечисленных ниже событий.

  • Очистка хранилища данных для соответствующего сайта в браузере.
  • Изменения в файле манифеста. Обратите внимание: обновление файла, указанного в манифесте, не означает, что браузер повторно кэширует этот ресурс. Для этого должен измениться сам файл манифеста.
  • Программное обновление кэша приложения.

Статус кэша

Программный доступ к кэшу приложения в браузере обеспечивает объект window.applicationCache. Его свойство status позволяет проверить текущее состояние кэша:

var appCache = window.applicationCache;

switch (appCache.status) {
	case appCache.UNCACHED: // UNCACHED == 0
		return 'UNCACHED';
		break;
	case appCache.IDLE: // IDLE == 1
		return 'IDLE';
		break;
	case appCache.CHECKING: // CHECKING == 2
		return 'CHECKING';
		break;
	case appCache.DOWNLOADING: // DOWNLOADING == 3
		return 'DOWNLOADING';
		break;
	case appCache.UPDATEREADY:  // UPDATEREADY == 4
		return 'UPDATEREADY';
		break;
	case appCache.OBSOLETE: // OBSOLETE == 5
		return 'OBSOLETE';
		break;
	default:
		return 'UKNOWN CACHE STATUS';
		break;
};

Чтобы обновить кэш программным образом, нужно прежде всего вызвать функцию applicationCache.update(). Она попытается обновить кэш пользователя (для этого необходимо, чтобы файл манифеста изменился). После того как атрибут applicationCache.status перейдет в состояние UPDATEREADY, функция applicationCache.swapCache() заменит старый кэш на новый.

var appCache = window.applicationCache;

appCache.update(); // Attempt to update the user's cache.

...

if (appCache.status == window.applicationCache.UPDATEREADY) {
	appCache.swapCache();  // The fetch was successful, swap in the new cache.
}

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