Что такое URL-адрес BLOB-объекта и почему он используется?

352

У меня много проблем с BLOB-URL.

Я искал srcтег видео на YouTube и обнаружил, что видео srcвыглядит так:

src="blob:https://crap.crap"

Я открыл URL-адрес блоба, который был в srcвидео, оно показало ошибку. Я не могу открыть ссылку, но она работала с srcтегом. Как это возможно?

Требования:

  • Что такое BLOB-URL?
  • Почему это используется?
  • Могу ли я создать свой собственный URL-адрес BLOB-объекта на сервере?
  • Если у вас есть какие-либо дополнительные детали
Вакас Тахир
источник
2
Также stackoverflow.com/q/14952052/632951
Pacerier
3
По существу запрещает хотлинкинг. (как на YouTube)
facepalm42

Ответы:

351

URL-адреса BLOB- объектов (ref W3C , официальное имя) или URL-адреса объектов (ref. MDN и имя метода) используются с объектами Blob или File .

src = "blob: https: //crap.crap " Я открыл URL-адрес блоба, который был в src видео, он выдал ошибку, и я не могу открыть, но работал с тегом src, как это возможно?

URL-адреса BLOB-объектов могут создаваться только внутри браузера. URL.createObjectURL()создаст специальную ссылку на объект Blob или File, который позже может быть освобожден с помощью URL.revokeObjectURL(). Эти URL-адреса могут использоваться только локально в одном экземпляре браузера и в одном сеансе (т. Е. В жизни страницы / документа).

Что такое BLOB-URL?
Почему это используется?

Blob URL / Object URL - это псевдопротокол, позволяющий использовать объекты Blob и File в качестве источника URL для таких вещей, как изображения, ссылки для загрузки двоичных данных и т. Д.

Например, вы не можете передать необработанные байтовые данные объекта Image, поскольку он не знает, что с ним делать. Это требует, например, изображения (которые являются двоичными данными) для загрузки через URL-адреса. Это относится ко всему, что требует URL в качестве источника. Вместо того, чтобы загружать двоичные данные, а затем отправлять их обратно через URL, лучше использовать дополнительный локальный шаг, чтобы иметь доступ к данным напрямую, без прохождения через сервер.

Это также лучшая альтернатива Data-URI, которые представляют собой строки, закодированные как Base-64 . Проблема с Data-URI состоит в том, что каждый символ занимает два байта в JavaScript. Кроме того, добавляется 33% из-за кодировки Base-64. BLOB-объекты - это чистые двоичные байтовые массивы, которые не имеют значительных издержек, как Data-URI, что делает их более быстрыми и меньшими для обработки.

Могу ли я сделать свой собственный URL-адрес BLOB-объекта на сервере?

Нет, URL-адреса BLOB-объектов / URL-адреса объектов могут создаваться только внутри браузера. Вы можете создавать BLOB-объекты и получать объект File с помощью API-интерфейса File Reader, хотя BLOB означает просто Binary Large OBject и хранится в виде байтовых массивов. Клиент может запросить отправку данных как ArrayBuffer или как BLOB-объект. Сервер должен отправлять данные в виде чистых двоичных данных. Базы данных часто используют Blob для описания двоичных объектов, и, по сути, речь идет в основном о байтовых массивах.

если у вас есть, то дополнительная информация

Вам необходимо инкапсулировать двоичные данные как объект BLOB, а затем использовать URL.createObjectURL()для создания локального URL-адреса для него:

var blob = new Blob([arrayBufferWithPNG], {type: "image/png"}),
    url = URL.createObjectURL(blob),
    img = new Image();

img.onload = function() {
    URL.revokeObjectURL(this.src);     // clean-up memory
    document.body.appendChild(this);   // add image to DOM
}

img.src = url;                         // can now "stream" the bytes

Обратите внимание, что URLможет иметь префикс в браузерах webkit, поэтому используйте:

var url = (URL || webkitURL).createObjectURL(...);
Bakudan
источник
20
Последние 6 часов я пытался заставить PHP превратить URL-адрес объекта, переданный из AJAX, в файл изображения. Только когда я прочитал ваше объяснение, я понял, почему он не записывает данные в файл ... Ваше краткое и подробное объяснение положило конец моим страданиям. Спасибо.
Partack
4
@ K3N можно ли получить истинный источник URL-адреса BLOB-объекта вместо сгенерированного URL-адреса? Nest cam генерирует URL-адрес
блоба,
4
просветление для меня "BLOB просто означает двоичный большой объект"
canbax
6
Можно ли извлечь содержимое объекта blob / file и загрузить, что бы это ни было (изображение или видео)?
DFSFOT
4
Это может быть уместно для людей,
ApproachingDarknessFish
10

Эта функция Javascript направлена ​​на то, чтобы показать разницу между API-интерфейсом Blob File и Data API для загрузки JSON- файла в клиентском браузере:

/**
 * Save a text as file using HTML <a> temporary element and Blob
 * @author Loreto Parisi
 */

var saveAsFile = function(fileName, fileContents) {
    if (typeof(Blob) != 'undefined') { // Alternative 1: using Blob
        var textFileAsBlob = new Blob([fileContents], {type: 'text/plain'});
        var downloadLink = document.createElement("a");
        downloadLink.download = fileName;
        if (window.webkitURL != null) {
            downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
        } else {
            downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
            downloadLink.onclick = document.body.removeChild(event.target);
            downloadLink.style.display = "none";
            document.body.appendChild(downloadLink);
        }
        downloadLink.click();
    } else { // Alternative 2: using Data
        var pp = document.createElement('a');
        pp.setAttribute('href', 'data:text/plain;charset=utf-8,' +
            encodeURIComponent(fileContents));
        pp.setAttribute('download', fileName);
        pp.onclick = document.body.removeChild(event.target);
        pp.click();
    }
} // saveAsFile

/* Example */
var jsonObject = {"name": "John", "age": 30, "car": null};
saveAsFile('out.json', JSON.stringify(jsonObject, null, 2));

Функция называется как saveAsFile('out.json', jsonString);. Он создаст ByteStream, немедленно распознаваемый браузером, который загрузит сгенерированный файл напрямую, используя File API URL.createObjectURL.

В elseэтом можно увидеть тот же результат, полученный через hrefэлемент плюс API данных, но это имеет несколько ограничений, которых нет у API Blob.

loretoparisi
источник
1
Можете ли вы адаптировать это, чтобы сохранить видео из твита?
логика
3

Что такое BLOB-URL? Почему это используется?

BLOB - это просто последовательность байтов. Браузер распознает его как поток байтов. Используется для получения потока байтов из источника.

Объект Blob представляет файловый объект неизменяемых необработанных данных. BLOB-объекты представляют данные, которые не обязательно имеют собственный формат JavaScript. Интерфейс File основан на Blob, наследуя функциональность blob и расширяя его для поддержки файлов в системе пользователя.

Могу ли я сделать свой собственный URL-адрес BLOB-объекта на сервере?

Да, вы можете сделать это несколькими способами, например, попробуйте http://php.net/manual/en/function.ibase-blob-echo.php

Читайте больше на

Роберт
источник
2
Могу ли я получить какую-либо выгоду, используя BLOB-URL?
Вакас Тахир
Вы можете прочитать это, чтобы получить свой ответ. Очевидно, есть плюсы и минусы.
Роберт
4
Вы смешиваете Object-URL с BLOB. Object-URL - это псевдопротокол, позволяющий использовать BLOB-объекты в качестве источника URI.
4
В этом ответе есть некоторые существенные недостатки. Главным образом, как указывалось в предыдущем комментарии, некоторые очень разные понятия смешиваются ... и затем сжимаются в неполный и неправильный ответ.
Trs
2

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

HTML

<input type="file" id="fileInput">
<div> duration: <span id='sp'></span><div>

Javascript

var fileEl = document.querySelector("input");

fileEl.onchange = function(e) {


    var file = e.target.files[0]; // selected file

    if (!file) {
        console.log("nothing here");
        return;
    }

    console.log(file);
    console.log('file.size-' + file.size);
    console.log('file.type-' + file.type);
    console.log('file.acutalName-' + file.name);

    let start = performance.now();

    var mime = file.type, // store mime for later
        rd = new FileReader(); // create a FileReader

    if (/video/.test(mime)) {

        rd.onload = function(e) { // when file has read:


            var blob = new Blob([e.target.result], {
                    type: mime
                }), // create a blob of buffer
                url = (URL || webkitURL).createObjectURL(blob), // create o-URL of blob
                video = document.createElement("video"); // create video element
            //console.log(blob);
            video.preload = "metadata"; // preload setting

            video.addEventListener("loadedmetadata", function() { // when enough data loads
                console.log('video.duration-' + video.duration);
                console.log('video.videoHeight-' + video.videoHeight);
                console.log('video.videoWidth-' + video.videoWidth);
                //document.querySelector("div")
                //  .innerHTML = "Duration: " + video.duration + "s" + " <br>Height: " + video.videoHeight; // show duration
                (URL || webkitURL).revokeObjectURL(url); // clean up

                console.log(start - performance.now());
                // ... continue from here ...

            });
            video.src = url; // start video load
        };
    } else if (/image/.test(mime)) {
        rd.onload = function(e) {

            var blob = new Blob([e.target.result], {
                    type: mime
                }),
                url = URL.createObjectURL(blob),
                img = new Image();

            img.onload = function() {
                console.log('iamge');
                console.dir('this.height-' + this.height);
                console.dir('this.width-' + this.width);
                URL.revokeObjectURL(this.src); // clean-up memory
                console.log(start - performance.now()); // add image to DOM
            }

            img.src = url;

        };
    }

    var chunk = file.slice(0, 1024 * 1024 * 10); // .5MB
    rd.readAsArrayBuffer(chunk); // read file object

};

URL-адрес jsFiddle

https://jsfiddle.net/PratapDessai/0sp3b159/

Пратап Дессаи
источник
1. Какова цель отступа в вашем коде? Все остальные используют отступы для выделения логической структуры кода. 2. Ваш JSFiddle ничего не делает. Я пытался загрузить изображение и видео.
7vujy0f0hy