HTML5 File API дает сбой Chrome при использовании readAsDataURL для загрузки выбранного изображения - PullRequest
9 голосов
/ 02 июня 2011

Вот мой пример кода:

var input = document.createElement('input');
input.type = 'file';
document.body.appendChild(input);

input.addEventListener('change', function(){
    var file = input.files[0];

    var reader = new FileReader();
    reader.onload = function(e){
        var image = new Image();
        image.src = e.target.result;
    };
    reader.readAsDataURL(file);
});

Загрузите страницу, выберите большое изображение (я использую 2.9MB 4288x3216 изображение). Обновите страницу и выберите то же изображение. Результат? Вкладка вылетает! (Оу, Snap!)

Я предполагаю, что это ошибка в реализации Chrome File API, но мне бы очень хотелось, чтобы кто-то мог это подтвердить и, возможно, даже предложить обходной путь. Я действительно хочу иметь возможность показывать миниатюру фотографии без необходимости заходить на сервер для ее создания (даже если это только для Chrome и FF).

Кроме того, с моим примером кода выше, как только вы выбираете фотографию, вкладка начинает использовать примерно на 32 МБ больше памяти. Это, я думаю, ожидаемо, но меня беспокоит то, что память никогда не освобождается сборщиком мусора. Поэтому, если я продолжаю выбирать больше фотографий, я продолжаю потреблять больше памяти. Я не знаю, связано ли это с проблемой сбоя или нет, но это определенно проблема.

Спасибо за любую помощь!

1 Ответ

13 голосов
/ 10 июня 2011

Ошибка памяти может быть результатом этой ошибки: http://crbug.com/36142. По сути, Chrome кэширует данные: URL-адреса и в настоящее время не освобождает память при изменении img.src.Другая проблема заключается в том, что данные: URL-адреса дают 33% накладных расходов на данные, которые вы кодируете.Это означает, что вы фактически устанавливаете для изображения ресурс размером ~ 3,85 МБ, а не 2,9 МБ.

Поскольку вы не манипулируете контентом (фактическими байтами), нет необходимости читать содержимое файла.Один из вариантов - создать blob: url.Существует также явный метод отзыва, поэтому вы не столкнетесь с такими же проблемами кэширования памяти.Что-то вроде:

input.addEventListener('change', function(e) {
  var file = input.files[0];

  window.URL = window.webkitURL || window.URL; // Vendor prefixed in Chrome.

  var img = document.createElement('img');
  img.onload = function(e) {
    window.URL.revokeObjectURL(img.src); // Clean up after yourself.
  };
  img.src = window.URL.createObjectURL(file);
  document.body.appendChild(img);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...