¿Qué es una URL de blob y por qué se usa?


348

Tengo muchos problemas con la URL de blob.

Estaba buscando srcuna etiqueta de video en YouTube y descubrí que el video srcera como:

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

Abrí la URL del blob que estaba en srcel video, dio un error. No puedo abrir el enlace, pero funcionaba con la srcetiqueta. ¿Cómo es esto posible?

Requisitos:

  • ¿Qué es el blob URL?
  • ¿Por qué se usa?
  • ¿Puedo hacer mi propia URL de blob en un servidor?
  • Si tienes algún detalle adicional


3
Esencialmente no permite el hotlinking. (como youtube)
facepalm42

Respuestas:


349

Las URL de blob (ref W3C , nombre oficial) o las URL de objeto (ref. MDN y nombre del método) se utilizan con un objeto Blob o File .

src = "blob: https: //crap.crap " Abrí la URL del blob que estaba en el src del video, me dio un error y no puedo abrirlo, pero estaba trabajando con la etiqueta src, ¿cómo es posible?

Las URL de blob solo pueden ser generadas internamente por el navegador. URL.createObjectURL()creará una referencia especial al objeto Blob o File que luego se puede liberar usando URL.revokeObjectURL(). Estas URL solo se pueden usar localmente en la única instancia del navegador y en la misma sesión (es decir, la vida útil de la página / documento).

¿Qué es blob url?
¿Por qué se usa?

Blob URL / Object URL es un pseudo protocolo para permitir que los objetos Blob y File se utilicen como fuente de URL para cosas como imágenes, enlaces de descarga para datos binarios, etc.

Por ejemplo, no puede entregar un objeto de imagen datos de bytes en bruto ya que no sabría qué hacer con él. Requiere, por ejemplo, imágenes (que son datos binarios) para cargarse a través de URL. Esto se aplica a todo lo que requiera una URL como fuente. En lugar de cargar los datos binarios, luego devolverlos a través de una URL, es mejor usar un paso local adicional para poder acceder a los datos directamente sin pasar por un servidor.

También es una mejor alternativa a Data-URI, que son cadenas codificadas como Base-64 . El problema con Data-URI es que cada carácter toma dos bytes en JavaScript. Además de eso, se agrega un 33% debido a la codificación Base-64. Los blobs son conjuntos de bytes binarios puros que no tienen una sobrecarga significativa como lo hace Data-URI, lo que los hace más rápidos y pequeños de manejar.

¿Puedo hacer mi propia URL de blob en un servidor?

No, las URL de blob / URL de objeto solo se pueden hacer internamente en el navegador. Puede hacer Blobs y obtener un objeto File a través de la API de File Reader, aunque BLOB solo significa Binary Large OBject y se almacena como conjuntos de bytes. Un cliente puede solicitar que los datos se envíen como ArrayBuffer o como Blob. El servidor debe enviar los datos como datos binarios puros. Las bases de datos a menudo usan Blob para describir objetos binarios también, y en esencia estamos hablando básicamente de conjuntos de bytes.

si tienes entonces Detalles adicionales

Debe encapsular los datos binarios como un objeto BLOB, luego usar URL.createObjectURL()para generar una URL local para él:

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

Tenga en cuenta que URLpuede tener el prefijo en webkit-browsers, así que use:

var url = (URL || webkitURL).createObjectURL(...);

19
Durante las últimas 6 horas he estado tratando de hacer que PHP convierta una URL de objeto pasada de AJAX a un archivo de imagen. No fue hasta que leí su explicación que me di cuenta de por qué no estaba escribiendo ningún dato en el archivo. Su explicación concisa y exhaustiva ha puesto fin a mi miseria. Gracias.
Partack el

44
@ K3N ¿es posible obtener la verdadera fuente de la URL del blob en lugar de la URL generada? Nest cam genera una URL de blob para evitar que las personas
graben

44
iluminación para mí "BLOB solo significa
Objeto

66
¿Es posible recuperar el contenido del objeto blob / archivo y descargar lo que sea (imagen o video)?
DFSFOT

44
Esto podría ser pertinente para las personas que se preguntan cómo descargar un video blob: stackoverflow.com/q/42901942/1530508
ApproachingDarknessFish

10

Esta función Javascript pretende mostrar la diferencia entre la API de archivos Blob y la API de datos para descargar un archivo JSON en el navegador del cliente:

/**
 * 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));

La función se llama like saveAsFile('out.json', jsonString);. Creará un ByteStream inmediatamente reconocido por el navegador que descargará el archivo generado directamente utilizando la API de archivo URL.createObjectURL.

En el else, es posible ver el mismo resultado obtenido a través del hrefelemento más la API de datos, pero esto tiene varias limitaciones que la API Blob no tiene.


1
¿Puedes adaptar esto para guardar un video de un tweet?
logicbloke

3

¿Qué es blob url? ¿Por qué se usa?

BLOB es solo una secuencia de bytes. El navegador lo reconoce como flujo de bytes. Se utiliza para obtener el flujo de bytes desde la fuente.

Un objeto Blob representa un objeto similar a un archivo de datos inmutables sin procesar. Los blobs representan datos que no están necesariamente en un formato nativo de JavaScript. La interfaz de archivo se basa en Blob, hereda la funcionalidad de blob y la expande para admitir archivos en el sistema del usuario.

¿Puedo hacer mi propia URL de blob en un servidor?

Sí, puede, hay varias formas de hacerlo, por ejemplo, intente http://php.net/manual/en/function.ibase-blob-echo.php

Leer más en


2
¿Puedo obtener algún beneficio utilizando la URL BLOB?
Waqas Tahir

Puedes leer esto para obtener tu respuesta. Obviamente hay pros y contras.
Robert

44
Está mezclando URL de objeto con BLOB. Object-URL es un pseudo protocolo para permitir que los BLOB se utilicen como fuente de URI.

44
Hay algunos defectos importantes con esta respuesta. Principalmente como se señaló en un comentario anterior, algunos conceptos muy diferentes se mezclan ... y luego se comprimen en una respuesta incompleta e incorrecta.
TRS

2

He modificado la solución de trabajo para manejar tanto el caso ... cuando se carga el video como cuando se carga la imagen ... espero que ayude un poco.

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

};

jsFiddle Url

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


1. ¿Cuál es el propósito de la sangría en su código? Todos los demás usan sangría para resaltar la estructura lógica del código. 2. Su JSFiddle no hace nada. Traté de subir una imagen y un video.
7vujy0f0hy
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.