Как долго сохраняется Blob?

Я пытаюсь написать отказоустойчивую программу, которая использует холст для рисования очень больших изображений (60 МБ, вероятно, является верхним диапазоном, а 10 МБ — нижним диапазоном). Я давно обнаружил, что вызов синхронной функции холста toDataURL обычно приводит к сбою страницы в браузере, поэтому я адаптировал программу для использования метода toBlob с помощью заполнителя для кросс-браузерной совместимости. Мой вопрос заключается в следующем: как долго сохраняются URL-адреса BLOB-объектов, использующие метод URL.createObjectURL(blob)?

Я хотел бы знать, есть ли способ кэшировать URL-адрес BLOB-объекта, который позволит ему длиться за пределами сеанса браузера, если кто-то захочет отобразить часть изображения в какой-то момент, закрыть браузер и вернуться и закончить его позже, снова считывая URL-адрес BLOB-объекта на холст и возобновляя его с того места, где он был остановлен. Я заметил, что этот необязательный аргумент autoRevoke может быть тем, что я ищу, но мне нужно подтверждение что то, что я пытаюсь сделать, на самом деле возможно. В вашем ответе не нужен пример кода, если он не включает другое решение, все, что мне нужно, это да или нет, если возможно сделать URL-адрес BLOB-объекта последним после сеансов с использованием этого метода или иным образом. (Это также было бы удобно, если по какой-то причине происходит сбой страницы, и это также действует как опция «восстановить сеанс».)

Я думал о чем-то вроде этого:

function saveCache() {
  var canvas = $("#canvas")[0];
  canvas.toBlob(function (blob) {
    /*if I understand correctly, this prevents it from unloading
      automatically after one asynchronous callback*/
    var blobURL = URL.createObjectURL(blob, {autoRevoke: false});
    localStorage.setItem("cache", blobURL);
  });
}

//assume that this might be a new browser session

function loadCache() {
  var url = localStorage.getItem("cache");
  if(typeof url=="string") {
    var img = new Image();
    img.onload = function () {
      $("#canvas")[0].getContext("2d").drawImage(img, 0, 0);
      //clear cache since it takes up a LOT unused of memory
      URL.revokeObjectURL(url);
      //remove reference to deleted cache
      localStorage.removeItem("cache");
      init(true); //cache successfully loaded, resume where it left off
    };
    img.onprogress = function (e) {
      //update progress bar
    };
    img.onerror = loadFailed; //notify user of failure
    img.src = url;
  } else {
    init(false); //nothing was cached, so start normally
  }
}

Обратите внимание, что я не уверен, что это будет работать так, как я задумал, поэтому любое подтверждение будет потрясающим.

EDIT только что понял, что sessionStorage — это не то же самое, что localStorage :P


person Patrick Roberts    schedule 20.12.2012    source источник
comment
Я только что почти точно проверил, что это за код, и он работает, когда вы обновляете страницу, но когда сеанс закрывается, localStorage сохраняется, но blobURL не...   -  person Patrick Roberts    schedule 20.12.2012
comment
Патрик, что произойдет, если вы уйдете, а затем нажмете кнопку "Назад"?   -  person Jonathan F    schedule 21.12.2012
comment
То же самое, что и при обновлении страницы, потому что это все тот же сеанс.   -  person Patrick Roberts    schedule 22.12.2012
comment
Привет @PatrickRoberts, у меня есть вопрос: stackoverflow.com/questions/67015438/   -  person Zedd    schedule 09.04.2021


Ответы (1)


URL-адрес BLOB-объекта может сохраняться между сеансами? Не так, как ты хочешь.

URL-адрес представляет собой ссылку, представленную в виде строки, которую вы можете сохранить в localStorage, как и любую строку. Расположение, на которое указывает URL-адрес, — это то, что вам действительно нужно, и оно не будет сохраняться между сеансами.

При использовании URL.toObjectUrl() в сочетании с аргументом autoRevoke URL-адрес будет сохраняться до тех пор, пока вы не вызовете revokeObjectUrl или пока не будут выполнены шаги очистки выгружаемого документа. (шаги описаны здесь: http://www.w3.org/TR/html51/browsers.html#unloading-document-cleanup-steps)

Я предполагаю, что эти шаги выполняются, когда сеанс браузера истекает, поэтому цель вашего blobURL не может быть доступна в последующих сеансах.

Некоторые другие рассуждения по этому поводу: Как сохранить Результат window.URL.createObjectURL() для будущего использования?

Вышеизложенное приводит к рекомендации использовать API FileSystem для сохранения представления большого двоичного объекта вашего элемента холста. При первом запросе файловой системы вам нужно будет запросить ПОСТОЯННОЕ хранилище, и пользователь должен будет согласиться на постоянное хранение данных на его машине.

http://www.html5rocks.com/en/tutorials/file/filesystem/ имеет хороший учебник для начинающих все, что вам нужно.

person Jonathan F    schedule 21.12.2012
comment
Эти этапы очистки документа, кажется, происходят при каждой выгрузке документа, то есть задолго до истечения срока действия сеанса. - person Bergi; 21.12.2012
comment
@Bergi Это то, что я подумал, прочитав документы, но, по словам Патрика, это работает, когда вы обновляете страницу. Я предполагаю, что современные браузеры предотвращают эти шаги выгрузки до тех пор, пока окно не выгрузится (может быть, это то, что стоит за CTR + ALT + T, так хорошо возвращающим последнюю закрытую вкладку?). - person Jonathan F; 21.12.2012
comment
Похоже, что Browsing Context должен определить, когда выгружать конкретный Document (если только пользователь не заставит это сделать): w3.org/TR/html51/ - person Jonathan F; 21.12.2012
comment
Да, я уверен, что есть оптимизации; особенно для быстрой перезагрузки страницы. Но это не значит, что вы не должны полагаться на их работу :-) - person Bergi; 21.12.2012
comment
Я согласен. При дальнейшем рассмотрении спецификация требует, чтобы пользовательские агенты выполняли эти шаги при каждом переходе по странице. Сначала я подумал, что информация может храниться как часть объекта состояния опции, связанного с историей контекста просмотра. Он может быть там, но в спецификации File API четко указано, что пользовательский агент должен отозвать URL-адрес при выгрузке. Мне не удалось найти ссылки на то, как обрабатывается обновление в отношении выгрузки. Может случиться так, что вызывается запрос на выгрузку, но не последующая выгрузка. - person Jonathan F; 21.12.2012
comment
Спасибо за ваш ответ, касающийся FileSystem API. Я уже изучил его и планирую использовать. Единственным недостатком является requestQuota, мне нужно будет запросить около 50-100 МБ, если я хочу, чтобы большой двоичный объект был правильно кэширован, поэтому я надеялся, что аргумент autoRevoke в методе createObjectURL будет достаточным сокращением. - person Patrick Roberts; 22.12.2012
comment
@JonathanF, у меня есть вопрос: stackoverflow.com/questions/67015438/ - person Zedd; 09.04.2021