Введение
Становится все более важным, чтобы веб-приложения были доступны в автономном режиме. Да, все браузеры могут кэшировать страницы и ресурсы на длительные периоды времени, если им об этом сказать, но браузер может в любой момент удалить отдельные элементы из кэша, чтобы освободить место для других вещей. HTML5 устраняет некоторые неудобства автономной работы с помощью интерфейса ApplicationCache . Использование интерфейса кэша дает вашему приложению три преимущества:
- Офлайн-просмотр — пользователи могут просматривать весь ваш сайт, даже если они не в сети.
- Скорость — ресурсы поступают прямо с диска, без подключения к сети.
- Устойчивость — если ваш сайт выйдет из строя на «техническое обслуживание» (например, кто-то случайно все сломает), ваши пользователи получат возможность работать в автономном режиме.
Кэш приложения (или AppCache) позволяет разработчику указать, какие файлы браузер должен кэшировать и сделать доступными для автономных пользователей. Ваше приложение будет загружаться и работать правильно, даже если пользователь нажмет кнопку обновления, находясь в автономном режиме.
Файл манифеста кэша
Файл манифеста кэша представляет собой простой текстовый файл, в котором перечислены ресурсы, которые браузер должен кэшировать для автономного доступа.
Ссылка на файл манифеста
Чтобы включить кэш приложения для приложения, включите атрибут манифеста в тег html
документа:
<html manifest="example.appcache">
...
</html>
Атрибут manifest
должен быть включен на каждую страницу вашего веб-приложения, которую вы хотите кэшировать. Браузер не кэширует страницу, если она не содержит атрибут manifest
(если только он явно не указан в самом файле манифеста. Это означает, что любая страница, на которую переходит пользователь и которая содержит manifest
будет неявно добавлена в кеш приложения. Таким образом, , нет необходимости перечислять каждую страницу в манифесте. Если страница указывает на манифест, невозможно предотвратить кэширование этой страницы.
Вы можете увидеть URL-адреса, которые контролируются кешем приложения, посетив about://://appcache-internals/ в Chrome. Отсюда вы можете очистить кеши и просмотреть записи. Подобные инструменты разработчика есть и в Firefox.
Атрибут manifest
может указывать на абсолютный URL-адрес или относительный путь, но абсолютный URL-адрес должен иметь тот же источник, что и веб-приложение. Файл манифеста может иметь любое расширение, но должен иметь правильный mime-тип (см. ниже).
<html manifest="http://www.example.com/example.mf">
...
</html>
Файл манифеста должен предоставляться с text/cache-manifest
. Возможно, вам придется добавить собственный тип файла в конфигурацию вашего веб-сервера или .htaccess
.
Например, чтобы использовать этот mime-тип в Apache, добавьте эту строку в свой файл конфигурации:
AddType text/cache-manifest .appcache
Или в файле app.yaml в Google App Engine:
- url: /mystaticdir/(.*\.appcache)
static_files: mystaticdir/\1
mime_type: text/cache-manifest
upload: mystaticdir/(.*\.appcache)
Это требование было исключено из спецификации некоторое время назад и больше не требуется в последних версиях Chrome, Safari и Firefox, но вам понадобится тип mime для работы в старых браузерах и IE11.
Структура файла манифеста
Манифест — это отдельный файл, на который вы ссылаетесь через атрибут манифеста в элементе html. Простой манифест выглядит примерно так:
CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
http://cdn.example.com/scripts/main.js
В этом примере будут кэшироваться четыре файла на странице, которая указывает этот файл манифеста.
Есть несколько вещей, на которые следует обратить внимание:
- Строка
CACHE MANIFEST
является первой строкой и является обязательной. - Файлы могут быть из другого домена
- Некоторые браузеры накладывают ограничения на объем квоты хранилища, доступной вашему приложению. Например, в Chrome AppCache использует общий пул ВРЕМЕННОГО хранилища, к которому могут совместно использовать другие автономные API. Если вы пишете приложение для Интернет-магазина Chrome , использование
unlimitedStorage
снимает это ограничение. - Если сам манифест возвращает 404 или 410, кеш удаляется.
- Если манифест или указанный в нем ресурс не удается загрузить, весь процесс обновления кэша завершается с ошибкой. В случае сбоя браузер продолжит использовать старый кеш приложения.
Давайте рассмотрим более сложный пример:
CACHE MANIFEST
# 2010-06-18:v2
# 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:
*
# 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
Строки, начинающиеся с символа «#», являются строками комментариев, но могут служить и другим целям. Кэш приложения обновляется только при изменении его файла манифеста. Например, если вы редактируете ресурс изображения или меняете функцию JavaScript, эти изменения не будут повторно кэшироваться. Вы должны изменить сам файл манифеста, чтобы сообщить браузеру о необходимости обновления кэшированных файлов .
Избегайте использования постоянно обновляемой отметки времени или случайной строки, чтобы каждый раз принудительно обновлять данные. Манифест проверяется дважды во время обновления: один раз в начале и один раз после обновления всех кэшированных файлов. Если манифест изменился во время обновления, возможно, браузер извлек некоторые файлы из одной версии, а другие файлы из другой версии, поэтому он не применяет кеш и повторяет попытку позже.
Хотя кэш обновляется, браузер не будет использовать эти файлы до тех пор, пока страница не будет обновлена, поскольку обновления происходят после загрузки страницы из текущей версии кэша.
Манифест может иметь три отдельных раздела: CACHE
, NETWORK
и FALLBACK
.
-
CACHE:
- Это раздел по умолчанию для записей. Файлы, перечисленные под этим заголовком (или сразу после
CACHE MANIFEST
), будут явно кэшироваться после первой загрузки.NETWORK:
- Файлы, перечисленные в этом разделе, могут поступать из сети, если их нет в кеше, иначе сеть не используется, даже если пользователь находится в сети. Здесь вы можете внести в белый список определенные URL-адреса или просто " ", что разрешает все URL-адреса. Большинству сайтов требуется " ".
FALLBACK:
- Необязательный раздел, определяющий резервные страницы, если ресурс недоступен. Первый URI — это ресурс, второй — резервный вариант, используемый в случае сбоя или ошибки сетевого запроса. Оба URI должны иметь то же происхождение, что и файл манифеста. Вы можете захватывать определенные URL-адреса, а также префиксы URL-адресов. «images/large/» будет фиксировать сбои с таких URL-адресов, как «images/large/whatever/img.jpg».
Следующий манифест определяет «универсальную» страницу (offline.html), которая будет отображаться, когда пользователь попытается получить доступ к корню сайта в автономном режиме. Он также заявляет, что все остальные ресурсы (например, находящиеся на удаленном сайте) требуют подключения к Интернету.
CACHE MANIFEST
# 2010-06-18:v3
# Explicitly cached entries
index.html
css/style.css
# offline.html will be displayed if the user is offline
FALLBACK:
/ /offline.html
# All other resources (e.g. sites) require the user to be online.
NETWORK:
*
# Additional resources to cache
CACHE:
images/logo1.png
images/logo2.png
images/logo3.png
Обновление кеша
Когда приложение находится в автономном режиме, оно остается в кэше до тех пор, пока не произойдет одно из следующих событий:
- Пользователь очищает хранилище данных своего браузера для вашего сайта.
- Файл манифеста изменен. Примечание. Обновление файла, указанного в манифесте, не означает, что браузер повторно кэширует этот ресурс. Сам файл манифеста должен быть изменен.
Статус кэша
Объект 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.
}
Хорошая новость: вы можете это автоматизировать. Чтобы обновить пользователей до новейшей версии вашего сайта, настройте прослушиватель для отслеживания события updateready
при загрузке страницы:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
События AppCache
Как и следовало ожидать, для мониторинга состояния кэша доступны дополнительные события. Браузер генерирует события для таких вещей, как ход загрузки, обновление кеша приложения и состояния ошибок. Следующий фрагмент настраивает прослушиватели событий для каждого типа событий кэша:
function handleCacheEvent(e) {
//...
}
function handleCacheError(e) {
alert('Error: Cache failed to update!');
};
// Fired after the first cache of the manifest.
appCache.addEventListener('cached', handleCacheEvent, false);
// Checking for an update. Always the first event fired in the sequence.
appCache.addEventListener('checking', handleCacheEvent, false);
// An update was found. The browser is fetching resources.
appCache.addEventListener('downloading', handleCacheEvent, false);
// The manifest returns 404 or 410, the download failed,
// or the manifest changed while the download was in progress.
appCache.addEventListener('error', handleCacheError, false);
// Fired after the first download of the manifest.
appCache.addEventListener('noupdate', handleCacheEvent, false);
// Fired if the manifest file returns a 404 or 410.
// This results in the application cache being deleted.
appCache.addEventListener('obsolete', handleCacheEvent, false);
// Fired for each resource listed in the manifest as it is being fetched.
appCache.addEventListener('progress', handleCacheEvent, false);
// Fired when the manifest resources have been newly redownloaded.
appCache.addEventListener('updateready', handleCacheEvent, false);
Если файл манифеста или указанный в нем ресурс не удалось загрузить, произойдет сбой всего обновления. В случае такого сбоя браузер продолжит использовать старый кэш приложения.
Ссылки
- Спецификация API ApplicationCache
- Application Cache — это придурок , освещающий ошибки и проблемы с AppCache.