Статьи

HTML5: автономная загрузка изображений

В настоящее время я работаю над приложением, которое должно работать в автономном режиме. Это имеет положительный побочный эффект, мы используем различные возможности хранения HTML5. Одним из них является File API , который мы используем для локального хранения изображений, прежде чем ставить их в очередь для загрузки на внутренний сервер.

В этой статье я поделюсь некоторым кодом, как мы это сделали. Пример работает в Google Chrome — для манипулирования DOM я буду использовать JQuery.

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

1
2
3
4
<body>
 <input type="file" accept="image/*" class="js-image-upload"/>
 <div class="js-image-container"></div>
</body>

Когда пользователь выбирает файл, мы хотим сохранить изображение.

1
2
3
4
5
6
$(document).on('change', '.js-image-upload', function (event) {
  var file = event.target.files[0];
  var fileName = createTempName(file);
 
  writeImage(fileName, file);
});

Хранение изображений осуществляется этим методом.

01
02
03
04
05
06
07
08
09
10
11
function writeImage(fileName, file) {
  getFileSystem(function (fileSystem) {
    fileSystem.root.getFile(fileName, {create: true}, function (fileEntry) {
      fileEntry.createWriter(function (fileWriter) {
        fileWriter.onwriteend = writeSuccessFull;
        fileWriter.onerror = errorFct;
        fileWriter.write(file);
      }, errorFct);
    });
  });
}

Что здесь происходит?

  • Получить файловую систему
  • Создайте файл по указанному имени в его корне
  • Создать писателя для этого файла
  • Сконфигурируйте успешный и ошибочный обратный вызов, когда происходит асинхронная запись файла
  • Напишите блоб файла, используя писателя

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

1
2
3
4
5
6
var SIZE = 100 * 1024 * 1024; // 100 MB
var getFileSystem = function (successFct) {
  navigator.webkitPersistentStorage.requestQuota(SIZE, function () {
    window.webkitRequestFileSystem(window.PERSISTENT, SIZE, successFct, errorFct);
  }, errorFct);
};

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

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

01
02
03
04
05
06
07
08
09
10
var showImage = function (fileName) {
  var src = 'filesystem:' + window.location.origin + '/persistent/' + fileName;
  var img = $('<img>').attr('src', src);
  $('.js-image-container').append(img);
};
 
var writeSuccessFull = function () {
  addToSyncQueue(fileName);
  showImage(fileName);
};

Я опускаю логику очереди здесь. Вы можете сохранить очередь изображений для загрузки в веб-хранилище или IndexedDB вашего приложения. Чтобы прочитать изображение из хранилища, вы можете использовать что-то вроде этого:

01
02
03
04
05
06
07
08
09
10
var readImage = function (fileName, successFct) {
  getFileSystem(function (fileSystem) {
    fileSystem.root.getFile(fileName, {}, function (fileEntry) {
 
        fileEntry.file(successFct, errorFct);
 
      }, errorFct);
    }
  );
};

Итак, это краткий обзор того, что мы сделали здесь. Рабочий пример кода можно найти здесь: https://gist.github.com/jthoenes/3668856a188d600e02d6

Надеюсь, что это было полезно для нескольких людей, имеющих дело с подобными проблемами. Не стесняйтесь задавать вопросы, когда что-то всплывает у вас в голове.