Как использовать webkitRequestFileSystem в файле: протокол

Согласно Изучение API файловой системы на

Поддержка браузера и ограничения на хранение

Вам может понадобиться флаг --allow-file-access-from-files, если вы отлаживаете свое приложение из file://. Неиспользование этих флагов приведет к SECURITY_ERR или QUOTA_EXCEEDED_ERR FileError.

Запущен хром с --allow-file-access-from-files , --unlimited-storage и, возможно, устаревшим --unlimited-quota-for-files; также --unsafely-treat-insecure-origin-as-secure=file:///path/to/directory/* с --user-data-dir=/path/to/directory набором.

Интересно, что при открытии хрома отображается уведомление

Вы используете неподдерживаемый флаг командной строки: --unsafely-treat-insecure-origin-as-secure. Стабильность и безопасность пострадают.

Есть и другие неуказанные флаги, которые можно использовать; проигнорировал уведомление, так как все еще мог установить и получить localStorage по протоколу file:, особенно файлы по file:///path/to/directory/*, хотя

navigator.webkitTemporaryStorage.requestQuota(1024*1024, function(grantedBytes) {
  console.log(grantedBytes)
}, errorHandler);

зарегистрирован 0, где errorHandler

function errorHandler(e) {
  console.log(e)
}

Также

function writeFile(fs) {
  fs.root.getFile("file.txt", {create: true}, function(fileEntry) {
    fileEntry.createWriter(function(fileWriter) {
      fileWriter.onwriteend = function(e) {
        // call `readFile`
        window.requestFileSystem(window.TEMPORARY, 1024*1024, readFile, errorHandler);
      };
      fileWriter.onerror = errorHandler;
      var blob = new Blob(["abc"], {type: "text/plain"});
      fileWriter.write(blob);
    }, errorHandler);
  }, errorHandler);
}

window.requestFileSystem(window.TEMPORARY, 1024*1024, writeFile, errorHandler);

function readFile(fs) {
  fs.root.getFile("file.txt", {}, function(fileEntry) {
    fileEntry.file(function(file) {
       var reader = new FileReader();
       reader.onloadend = function(e) {
         console.log(e.target.result)
       };
       reader.readAsText(file);
    }, errorHandler);
  }, errorHandler);
}

зарегистрирован

FileError {code: 7, name: "InvalidStateError", message: "An operation that depends on state cached in an in…he state had changed since it was read from disk."}
code:7
message:"An operation that depends on state cached in an interface object was made but the state had changed since it was read from disk."
name:"InvalidStateError"
__proto__:DOMError

Вопрос: Какие изменения необходимы при запуске флагов, обходные пути или другие подходы, которые позволили бы использовать протокол webkitRequestFileSystem at file:?


person guest271314    schedule 28.05.2016    source источник
comment
Я не получил эту ошибку или 0 вместо grantedBytes при тестировании. Использованы все перечисленные вами флаги, кроме: --unsafely-treat-insecure-origin-as-secure, --unlimited-quota-for-files, --unlimited-storage. Единственное изменение, которое я должен был сделать, было то, что при желании сделать постоянные данные нужно было сначала использовать navigator.webkitPersistentStorage.requestQuota.   -  person Patrick Evans    schedule 28.05.2016
comment
@PatrickEvans Удалось ли вам написать FileSystem по протоколу file:? Какая версия хрома или хрома? Можете ли вы опубликовать файл .html, который вы протестировали в протоколе file: и js использовали в файле .html?   -  person guest271314    schedule 28.05.2016
comment
Да, он записал файл с abc внутри как для временного, так и для постоянного. Я попробовал это как с Chrome (50.0.2661.102 m), так и с Chromium (53.0.2752.0) в Windows 10. Конечно, я отредактирую ссылку через секунду.   -  person Patrick Evans    schedule 28.05.2016
comment
Версия постоянного хранилища, Версия временного хранилища и переключатели командной строки: --allow-file-access-from-files --user-data-dir=/path/to/my/Desktop/data. И был запущен с использованием URL-адреса файла: file:///C:/Users/polar/Desktop/test.html   -  person Patrick Evans    schedule 28.05.2016
comment
@PatrickEvans Первая протестированная версия хрома была ошибкой пользователя; диск был заполнен. Не уверен, почему вторая версия тестировала зарегистрированную ошибку. Удалось написать FileSystem в file: с третьей попытки, установив хром 50.0.2661.102 на живую ОС.   -  person guest271314    schedule 28.05.2016
comment
@PatrickEvans Возможно, использовалась старая папка конфигурации профиля; использовал другую папку конфигурации хрома в той же версии, и ожидаемый результат был достигнут.   -  person guest271314    schedule 29.05.2016


Ответы (1)


При первой попытке были получены ошибки terminal, связанные с нехваткой места на устройстве. Получены две отдельные ошибки code 7 InvalidStateError и code 3 AbortError. Обратите внимание, что на каждой конфигурации хром запускался в песочнице.

Удалось добиться ожидаемого результата записи в FileSystem по протоколу file:, установив флаги запуска на --allow-file-access-from-files и указав другую папку конфигурации хрома в --user-data-dir=/newer/version/of/profile/folder; --unlimited-quota-for-files и --unsafely-treat-insecure-origin-as-secure=file:///path/to/directory/* не были необходимы для выполнения требования.

Не совсем понятно, почему исходная папка профиля использовала зарегистрированные ошибки при попытке доступа к FileSystem по протоколу file:. Папка могла быть из предыдущей версии хрома. Как правило, запускайте новую или новейшую версию хрома из командной строки, где папка chromium в каталоге конфигурации может быть более старой версией с уже установленными настройками. При просмотре terminal в какой-то момент было зарегистрировано сообщение no space left on disk относительно FileSystem при запуске с использованием прежней папки конфигурации профиля. Пробовал более новую версию папки профиля хрома, которая решила проблему.

Большая заслуга в решении принадлежит @PatrickEvans за проверку того, что процесс действительно возможен; что это, скорее всего, была ошибка пользователя, которая ограничивала реализацию ожидаемого результата.

var requestedBytes = 16,
  _grantedBytes;

function errorHandler(e) {
  console.log(e)
}

function writeFile(fs) {
  console.log(fs)
  fs.root.getFile("file.txt", {
    create: true
  }, function(fileEntry) {
    fileEntry.createWriter(function(fileWriter) {
      fileWriter.onwriteend = function(e) {
        // call `readFile`
        console.log(_grantedBytes);
        window.webkitRequestFileSystem(window.TEMPORARY
                                      , _grantedBytes
                                      , readFile
                                      , errorHandler);
      };
      fileWriter.onerror = errorHandler;
      var blob = new Blob(["abc"], {
        type: "text/plain"
      });
      fileWriter.write(blob);
    }, errorHandler);
  }, errorHandler);
}

navigator.webkitTemporaryStorage.requestQuota(requestedBytes
, function(grantedBytes) {
    console.log(grantedBytes);
    _grantedBytes = grantedBytes;
    window.webkitRequestFileSystem(window.TEMPORARY
                                  , grantedBytes
                                  , writeFile
                                  , errorHandler);

}, errorHandler);

function readFile(fs) {
  fs.root.getFile("file.txt", {}, function(fileEntry) {
    fileEntry.file(function(file) {
      var reader = new FileReader();
      reader.onloadend = function(e) {
        console.log(e.target.result, fileEntry.toURL());
      };
      reader.readAsText(file);
    }, errorHandler);
  }, errorHandler);
}
person guest271314    schedule 28.05.2016
comment
Приятно видеть проверенный функциональный рабочий пример. СПАСИБО. (За исключением первых двух экземпляров console.log() без точек с запятой). Все работало нормально, кроме этого. - person www-0av-Com; 30.10.2017