API-интерфейс Html5 - использование BLOB?

У меня есть входной файл: (jsbin)

 <input type="file"   accept="image/*" id="input" multiple   onchange='handleFiles(this)' />

Что, когда выбран файл, показывает небольшие изображения выбранного изображения:

Я могу сделать это в двумя способами:

с помощью FileReader:

function handleFiles(t) //t=this
{
    var fileList = t.files;
    for (var i = 0; i < fileList.length; i++)
    {
        var file = fileList[i];
        var img = document.createElement("img");
        img.style... = ...
        document.getElementById('body').appendChild(img);
        var reader = new FileReader();
        reader.onload = (function (aImg)
        {
            return function (e)
            {
                aImg.src = e.target.result;
            };
        })(img);
        reader.readAsDataURL(file);
    }
    // ...
}

с помощью ObjectURL/BLOB:

 function handleFiles(t)
 {
     var fileList = t.files;
     for (var i = 0; i < fileList.length; i++)
     {
         var file = fileList[i];
         var img = document.createElement("img");
         img.src = window.URL.createObjectURL(file);
         img.onload = function (e)
         {
             window.URL.revokeObjectURL(this.src);
         }
         document.getElementById('body').appendChild(img);
     }
 }

Как вы можете видеть, обе работают:

enter image description here

НО

Результат html отличается:

enter image description here

Вопрос:

С первым я уже знаю, что я могу сделать, это чистые данные-uri.

Но когда я должен использовать второй подход (blob)? Я имею ввиду - что я могу сделать blob:http%3A//run.jsbin.com/82b29cc5-8452-4ae2-80ca-a949898f4295?

p.s. mdn объяснение о URL.createObjectURL не помогает мне, когда я должен использовать каждый.

Ответ 1

Длина URL blob: всегда ниже разумного предела.

URL-адреса данных могут быть произвольными большими. Следовательно, когда URL-адрес данных слишком длинный, некоторые браузеры (IE, cough) больше не будут отображать изображение. Таким образом, если вы хотите отображать очень большие файлы, использование blob: (или filesystem: URL-адресов) может иметь больше смысла, чем URL-адреса данных.


Кроме того, вы можете напрямую восстанавливать данные с blob: URL (при условии, что blob еще не был отозван, например, потому что документ был выгружен, а одна и та же политика происхождения не нарушена) используя XMLHttpRequest. Например, следующий код получает содержимое URL-адреса blob как текст:

var blobUrl = URL.createObjectURL(new Blob(['Test'], {type: 'text/plain'}));
var x = new XMLHttpRequest();
// set x.responseType = 'blob' if you want to get a Blob object:
// x.responseType = 'blob';
x.onload = function() {
    alert(x.responseText);
};
x.open('get', blobUrl);
x.send();

Если вы хотите отправить содержимое файла на сервер с помощью XMLHttpRequest, на самом деле не имеет смысла использовать blob: или data: URL. Просто отправьте объект File напрямую, используя объект FormData. Если вы потеряли исходную ссылку File, и у вас есть только URL blob:, вы можете использовать предыдущий фрагмент, чтобы снова получить объект Blob для использования в FormData.

Учитывая data: -URL, восстановить исходные данные не так просто. Firefox и Opera 12 - разрешить использование data: -URL в XMLHttpRequest. Chrome, Internet Explorer, Safari и Opera 15+ отказываются загружать URL-адрес данных через XMLHttpRequest. Таким образом, в отношении восстановления данных URL-адреса blob: также превосходят по сравнению с data: -URLs.

Если вы хотите отобразить результат файла в другом кадре в том же самом источнике, определенно используйте URL blob:. Если вы хотите манипулировать данными, содержащимися в Blob, в другом кадре (возможно, с другим происхождением), не использовать URL-адреса blob или данных, отправьте данные напрямую, используя postMessage.

blob: -URLs обычно лучше, чем data: -URLs для представления (двоичных) данных. Для небольших данных (max 20kb) URL-адреса data: могут быть лучшим выбором из-за более высокого диапазона поддерживаемых браузеров: Compare Могу ли я использовать URL-адреса Blob с Могу ли я использовать URI данных (хотя, если вы пишете сложное приложение HTML5, вероятность того, что вы не собираетесь поддержка IE9 -).

Ответ 2

Вот основные отличия в том, как вы можете использовать два типа URL-адресов:

URL-адреса данных:

Плюсы:

  • вы можете легко получить данные из них
  • вы можете отправить их другому пользователю или через HTTP, а данные все еще там
  • Неважно, где и как они были созданы, если данные действительны, вы увидите содержимое в любом браузере, на любой ОС, где угодно

Минусы:

  • URL-адреса данных часто являются чрезмерно длинными, поэтому IE может не справиться с ними, и это может раздражать обращение в любом браузере
  • Они менее эффективны, чем BLOB-URL (вам нужно прочитать файл для его создания, вы не используете BLOB файлы и т.д.).

URL-адреса BLOB:

Плюсы:

  • Они намного короче, чем URL-адреса данных, что делает их намного более управляемыми
  • вы можете получить доступ к своим данным, но поскольку URL-адрес является лишь непрозрачной ссылкой на данные, к данным следует обращаться с помощью FileReader, и данные не могут быть извлечены непосредственно из URL-адреса, как в URL-адресах данных
  • поскольку они имеют разумную длину, с ними легче справляться и иметь лучшую поддержку IE

Минусы:

  • Данные не доступны в самом URL-адресе (URL-адрес непрозрачной ссылки), и он не сохраняется в облаке
  • Из-за конфликта # 1 вы не можете отправить URL-адрес на сервер/другой пользователь, так как они не смогут получить доступ к данным. Так что URL-адрес только для вас.
  • Вы также не можете получить доступ к данным с URL-адреса BLOB в другом браузере (даже на том же компьютере)
  • Кроме того, вы не можете получить доступ к URL-адресу BLOB из другого источника, даже в том же браузере

В этом списке похоже, что URL-адреса данных являются очевидным преимуществом, но URL-адреса BLOB быстрее создавать, и, если вам не нужно отправлять URL-адрес другим пользователям или на сервер, вы должны использовать их, потому что они быстрее, проще в использовании, более управляемым и лучше для IE. Но если вам нужно отправить URL-адрес серверу или другому пользователю, я бы порекомендовал каким-то образом передать blob напрямую с помощью XHR2. URL-адреса данных не так уж хороши.