Почти каждый аспект разработки приложений включает в себя тот или иной элемент отправки или получения данных. Начиная с основ, вам следует использовать платформу MVC, которая поможет вам спроектировать и реализовать ваше приложение так, чтобы данные были полностью отделены от представления этих данных приложением (см. Архитектура MVC ).
Вам также необходимо подумать о том, как обрабатываются данные, когда ваше приложение находится в автономном режиме (см. «Сначала в автономном режиме »). В этом документе кратко представлены варианты хранения данных для отправки, получения и сохранения данных локально; В оставшейся части документа показано, как использовать API-интерфейсы файловой системы Chrome и синхронизации файловой системы (см. также API-интерфейсы fileSystem и syncFileSystem API ).
Варианты хранения
Упакованные приложения используют множество различных механизмов для отправки и получения данных. Для внешних данных (ресурсов, веб-страниц) необходимо знать Политику безопасности контента (CSP) . Подобно расширениям Chrome, вы можете использовать XMLHttpRequests из разных источников для связи с удаленными серверами. Вы также можете изолировать внешние страницы, чтобы остальная часть вашего приложения была в безопасности (см. Встраивание внешних веб-страниц ).
При локальном сохранении данных вы можете использовать Chrome Storage API для сохранения небольших объемов строковых данных и IndexedDB для сохранения структурированных данных. С помощью IndexedDB вы можете сохранять объекты JavaScript в хранилище объектов и использовать индексы хранилища для запроса данных (более подробную информацию см. в руководстве по простому списку задач HTML5 Rock). Для всех других типов данных, например двоичных данных, используйте API-интерфейсы файловой системы и синхронизации файловой системы.
API файловой системы и синхронизации файловой системы Chrome расширяют API файловой системы HTML5 . С помощью API файловой системы Chrome приложения могут создавать, читать, перемещаться и записывать в изолированный раздел локальной файловой системы пользователя. Например, приложение для обмена фотографиями может использовать API файловой системы для чтения и записи любых фотографий, которые выбирает пользователь.
С помощью API синхронизации файловой системы Chrome приложения могут сохранять и синхронизировать данные на Google Диске пользователя, чтобы одни и те же данные были доступны различным клиентам. Например, приложение для текстового редактора с поддержкой облака может автоматически синхронизировать новые текстовые файлы с учетной записью пользователя на Google Диске. Когда пользователь открывает текстовый редактор в новом клиенте, Google Диск отправляет новые текстовые файлы в этот экземпляр текстового редактора.
Использование API файловой системы Chrome
Добавление разрешения файловой системы
Чтобы использовать API файловой системы Chrome, вам необходимо добавить в манифест разрешение «fileSystem», чтобы вы могли получить от пользователя разрешение на хранение постоянных данных.
"permissions": [
"...",
"fileSystem"
]
Пользовательские параметры выбора файлов
Пользователи ожидают, что будут выбирать файлы так же, как они это делают всегда. Как минимум, они ожидают кнопку «Выбрать файл» и стандартный инструмент выбора файла. Если ваше приложение активно использует обработку файлов, вам также следует реализовать перетаскивание (см. ниже, а также ознакомьтесь со статьей Native HTML5 Drag and Drop ).
Получение пути к файлуEntry
Чтобы получить полный путь к файлу, выбранному пользователем, fileEntry
, вызовите getDisplayPath()
:
function displayPath(fileEntry) {
chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
console.log(path)
});
}
Реализация перетаскивания
Если вам нужно реализовать выбор методом перетаскивания, хорошей отправной точкой будет файловый контроллер перетаскивания ( dnd.js
) в примере доступа к файловой системе . Контроллер создает запись файла из DataTransferItem
посредством перетаскивания. В этом примере fileEntry
задан первый удаленный элемент.
var dnd = new DnDFileController('body', function(data) {
var fileEntry = data.items[0].webkitGetAsEntry();
displayPath(fileEntry);
});
Чтение файла
Следующий код открывает файл (только для чтения) и считывает его как текст с помощью объекта FileReader
. Если файл не существует, выдается ошибка.
var chosenFileEntry = null;
chooseFileButton.addEventListener('click', function(e) {
chrome.fileSystem.chooseEntry({type: 'openFile'}, function(readOnlyEntry) {
readOnlyEntry.file(function(file) {
var reader = new FileReader();
reader.onerror = errorHandler;
reader.onloadend = function(e) {
console.log(e.target.result);
};
reader.readAsText(file);
});
});
});
Написание файла
Двумя распространенными вариантами записи файла являются «Сохранить» и «Сохранить как». Следующий код создает writableEntry
из chosenFileEntry
доступного только для чтения, и записывает в него выбранный файл.
chrome.fileSystem.getWritableEntry(chosenFileEntry, function(writableFileEntry) {
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = callback;
chosenFileEntry.file(function(file) {
writer.write(file);
});
}, errorHandler);
});
Следующий код создает новый файл с функцией «Сохранить как» и записывает в него новый большой двоичный объект с помощью метода writer.write()
.
chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = function(e) {
console.log('write complete');
};
writer.write(new Blob(['1234567890'], {type: 'text/plain'}));
}, errorHandler);
});
Использование API файловой системы синхронизации Chrome
Используя синхронизируемое хранилище файлов, с возвращаемыми объектами данных можно работать так же, как с локальными автономными файловыми системами в API файловой системы , но с добавленной (и автоматической) синхронизацией этих данных с Google Диском.
Добавление разрешения на синхронизацию файловой системы
Чтобы использовать API синхронизации файловой системы Chrome, вам необходимо добавить в манифест разрешение «syncFileSystem», чтобы вы могли получить от пользователя разрешение на хранение и синхронизацию постоянных данных.
"permissions": [
"...",
"syncFileSystem"
]
Запуск синхронизируемого хранилища файлов
Чтобы инициировать синхронизируемое хранилище файлов в вашем приложении, просто вызовите syncFileSystem.requestFileSystem . Этот метод возвращает синхронизируемую файловую систему, поддерживаемую Google Диском, например:
chrome.syncFileSystem.requestFileSystem(function (fs) {
// FileSystem API should just work on the returned 'fs'.
fs.root.getFile('test.txt', {create:true}, getEntryCallback, errorCallback);
});
О статусе синхронизации файлов
Используйте syncFileSystem.getFileStatus , чтобы получить статус синхронизации текущего файла:
chrome.syncFileSystem.getFileStatus(entry, function(status) {...});
Значения состояния синхронизации файлов могут быть одним из следующих: 'synced'
, 'pending'
или 'conflicting'
. «Синхронизировано» означает, что файл полностью синхронизирован; нет ожидающих рассмотрения локальных изменений, которые не были синхронизированы с Google Диском. Однако на стороне Google Диска могут быть ожидающие изменения, которые еще не были загружены.
«Ожидание» означает, что в файле есть ожидающие изменения, которые еще не синхронизированы с Google Диском. Если приложение работает онлайн, локальные изменения (почти) немедленно синхронизируются с Google Диском, а событие syncFileSystem.onFileStatusChanged запускается со статусом 'synced'
(более подробную информацию см. ниже).
syncFileSystem.onFileStatusChanged запускается, когда статус файла меняется на 'conflicting'
. «Конфликт» означает, что в локальном хранилище и на Google Диске имеются конфликтующие изменения. Файл может находиться в этом состоянии только в том случае, если для политики разрешения конфликтов установлено значение 'manual'
. Политика по умолчанию — 'last_write_win'
и конфликты автоматически разрешаются с помощью простой политики «последняя запись выиграла». Системную политику разрешения конфликтов можно изменить с помощью syncFileSystem.setConflictResolutionPolicy .
Если для политики разрешения конфликтов установлено значение 'manual'
, а файл приводит к 'conflicting'
состоянию, приложение все равно может читать и записывать файл как локальный автономный файл, но изменения не синхронизируются, и файл сохраняется. отключен от удаленных изменений, внесенных на других клиентах, до разрешения конфликта. Самый простой способ разрешить конфликт — удалить или переименовать локальную версию файла. Это принудительно синхронизирует удаленную версию, конфликтное состояние разрешается, и событие onFileStatusChanged
запускается со статусом 'synced'
.
Прослушивание изменений в статусе синхронизации
Событие syncFileSystem.onFileStatusChanged вызывается при изменении состояния синхронизации файла. Например, предположим, что файл имеет ожидающие изменения и находится в состоянии «ожидания». Возможно, приложение находилось в автономном состоянии, поэтому изменения будут синхронизированы. Когда служба синхронизации обнаруживает ожидающее локальное изменение и загружает его на Google Диск, служба запускает событие onFileStatusChanged
со следующими значениями: { fileEntry:a fileEntry for the file, status: 'synced', action: 'updated', direction: 'local_to_remote' }
.
Аналогичным образом, независимо от локальных действий, служба синхронизации может обнаруживать удаленные изменения, внесенные другим клиентом, и загружает изменения с Google Диска в локальное хранилище. Если удаленное изменение было связано с добавлением нового файла, создается событие со следующими значениями: { fileEntry: a fileEntry for the file, status: 'synced', action: 'added', direction: 'remote_to_local' }
.
Если как на локальной, так и на удаленной стороне имеются конфликтующие изменения для одного и того же файла и если для политики разрешения конфликтов установлено значение 'manual'
, состояние файла изменяется на conflicting
состояние, он отсоединяется от службы синхронизации и не будет синхронизирован до тех пор, пока конфликт разрешен. В этом случае запускается событие со следующими значениями: { fileEntry: a fileEntry for the file, status: 'conflicting', action: null, direction: null }
.
Вы можете добавить прослушиватель этого события, который будет реагировать на любые изменения статуса. Например, приложение Chrome Music Player прослушивает любую новую музыку, синхронизированную с Google Диска, но еще не импортированную в локальное хранилище пользователя на конкретном клиенте. Любая найденная музыка синхронизируется с этим клиентом:
chrome.syncFileSystem.onFileStatusChanged.addListener(function(fileInfo) {
if (fileInfo.status === 'synced') {
if (fileInfo.direction === 'remote_to_local') {
if (fileInfo.action === 'added') {
db.add(fileInfo.fileEntry);
} else if (fileInfo.action === 'deleted') {
db.remove(fileInfo.fileEntry);
}
}
}
});
Проверка использования API
Чтобы проверить объем данных, используемых API, запросите локальный изолированный каталог приложения или байты использования, возвращаемые syncFileSystem.getUsageAndQuota :
chrome.syncFileSystem.getUsageAndQuota(fileSystem, function (storageInfo) {
updateUsageInfo(storageInfo.usageBytes);
updateQuotaInfo(storageInfo.quotaBytes);
});
Вы также можете просмотреть хранилище серверной службы синхронизации пользователя (на Google Диске). Синхронизированные файлы сохраняются в скрытой папке Google Диска Chrome Syncable FileSystem . Папка не будет отображаться в вашем списке «Мой диск», но к ней можно будет получить доступ, выполнив поиск по имени папки в поле поиска. (Обратите внимание, что макет удаленной папки не гарантирует обратную совместимость между выпусками.)