Was ist eine Blob-URL und warum wird sie verwendet?

348

Ich habe viele Probleme mit der Blob-URL.

Ich habe srcauf YouTube nach einem Video-Tag gesucht und festgestellt, dass das Video srcwie folgt aussieht:

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

Ich habe die Blob-URL srcdes Videos geöffnet, in dem ein Fehler aufgetreten ist. Ich kann den Link nicht öffnen, aber er hat mit dem srcTag funktioniert . Wie ist das möglich?

Bedarf:

  • Was ist eine Blob-URL?
  • Warum wird es verwendet?
  • Kann ich meine eigene Blob-URL auf einem Server erstellen?
  • Wenn Sie weitere Details haben
Waqas Tahir
quelle
3
Verbietet im Wesentlichen kein Hotlinking. (wie Youtube)
Facepalm42

Antworten:

349

Blob-URLs (Ref. W3C , offizieller Name) oder Objekt-URLs (Ref. MDN und Methodenname) werden mit einem Blob- oder einem Dateiobjekt verwendet .

src = " blob : https: //crap.crap " Ich habe die Blob-URL geöffnet, die sich in src des Videos befand. Es gab einen Fehler und ich kann sie nicht öffnen, aber habe ich mit dem src-Tag gearbeitet, wie ist das möglich?

Blob-URLs können nur intern vom Browser generiert werden. URL.createObjectURL()erstellt einen speziellen Verweis auf das Blob- oder File-Objekt, der später mit freigegeben werden kann URL.revokeObjectURL(). Diese URLs können nur lokal in der einzelnen Instanz des Browsers und in derselben Sitzung verwendet werden (dh die Lebensdauer der Seite / des Dokuments).

Was ist eine Blob-URL?
Warum wird es verwendet?

Blob-URL / Objekt-URL ist ein Pseudoprotokoll, mit dem Blob- und Dateiobjekte als URL-Quelle für Bilder, Download-Links für Binärdaten usw. verwendet werden können.

Beispielsweise können Sie einem Bildobjekt keine Rohbyte-Daten übergeben, da es nicht wissen würde, was damit zu tun ist. Beispielsweise müssen Bilder (Binärdaten) über URLs geladen werden. Dies gilt für alles, für das eine URL als Quelle erforderlich ist. Anstatt die Binärdaten hochzuladen und dann über eine URL zurückzusenden, ist es besser, einen zusätzlichen lokalen Schritt zu verwenden, um direkt auf die Daten zugreifen zu können, ohne über einen Server zu gehen.

Es ist auch eine bessere Alternative zu Daten-URI, bei denen es sich um als Base-64 codierte Zeichenfolgen handelt . Das Problem mit dem Daten-URI besteht darin, dass jedes Zeichen in JavaScript zwei Bytes benötigt. Darüber hinaus werden aufgrund der Base-64-Codierung 33% hinzugefügt. Blobs sind reine binäre Byte-Arrays, die keinen signifikanten Overhead haben wie Data-URI, wodurch sie schneller und kleiner zu handhaben sind.

Kann ich meine eigene Blob-URL auf einem Server erstellen?

Nein, Blob-URLs / Objekt-URLs können nur intern im Browser erstellt werden. Sie können Blobs erstellen und File-Objekte über die File Reader-API abrufen, obwohl BLOB nur Binary Large OBject bedeutet und als Byte-Arrays gespeichert wird. Ein Client kann anfordern, dass die Daten entweder als ArrayBuffer oder als Blob gesendet werden. Der Server sollte die Daten als reine Binärdaten senden. Datenbanken verwenden häufig Blob, um auch binäre Objekte zu beschreiben, und im Wesentlichen handelt es sich im Wesentlichen um Byte-Arrays.

Wenn Sie dann zusätzliche Details haben

Sie müssen die Binärdaten als BLOB-Objekt kapseln und dann URL.createObjectURL()eine lokale URL dafür generieren:

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

Beachten Sie, dass URLin Webkit-Browsern möglicherweise ein Präfix vorangestellt ist. Verwenden Sie daher:

var url = (URL || webkitURL).createObjectURL(...);
Bakudan
quelle
19
In den letzten 6 Stunden habe ich versucht, PHP dazu zu bringen, eine von AJAX übergebene Objekt-URL in eine Bilddatei umzuwandeln. Erst als ich Ihre Erklärung las, wurde mir klar, warum keine Daten in die Datei geschrieben wurden. Ihre präzise und gründliche Erklärung hat meinem Elend ein Ende gesetzt. Vielen Dank.
Partack
4
@ K3N ist es möglich, die wahre Quelle der Blob-URL anstelle der generierten URL zu erhalten? Nest Cam generiert eine Blob-URL, um zu verhindern, dass Personen ihre eigenen Kameras aufnehmen
Alex Kwitny
4
Erleuchtung für mich "BLOB bedeutet nur binäres großes Objekt"
canbax
6
Ist es möglich, den Inhalt des Blob- / Dateiobjekts abzurufen und alles herunterzuladen, was es ist (Bild oder Video)?
DFSFOT
4
Dies könnte für die Leute relevant sein, die sich fragen, wie man ein Blob-Video herunterlädt: stackoverflow.com/q/42901942/1530508
ApproachingDarknessFish
10

Diese Javascript-Funktion soll den Unterschied zwischen der Blob- Datei-API und der Daten- API zum Herunterladen einer JSON- Datei im Client-Browser anzeigen:

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

Die Funktion heißt wie saveAsFile('out.json', jsonString);. Es wird ein ByteStream erstellt, der vom Browser sofort erkannt wird und der die generierte Datei direkt über die Datei-API herunterlädt URL.createObjectURL.

In der elseist es möglich, dasselbe Ergebnis zu sehen, das über das hrefElement plus die Daten-API erhalten wurde, aber dies hat einige Einschränkungen, die die Blob-API nicht hat.

loretoparisi
quelle
1
Können Sie dies anpassen, um ein Video aus einem Tweet zu speichern?
Logicbloke
3

Was ist eine Blob-URL? Warum wird es verwendet?

BLOB ist nur eine Bytesequenz. Der Browser erkennt es als Byte-Stream. Es wird verwendet, um den Byte-Stream von der Quelle abzurufen.

Ein Blob-Objekt repräsentiert ein dateiähnliches Objekt unveränderlicher Rohdaten. Blobs stellen Daten dar, die nicht unbedingt in einem JavaScript-nativen Format vorliegen. Die Dateischnittstelle basiert auf Blob, erbt die Blob-Funktionalität und erweitert sie, um Dateien auf dem System des Benutzers zu unterstützen.

Kann ich meine eigene Blob-URL auf einem Server erstellen?

Ja, es gibt verschiedene Möglichkeiten, dies zu tun. Versuchen Sie beispielsweise http://php.net/manual/en/function.ibase-blob-echo.php

Lesen Sie mehr darüber

Robert
quelle
2
Kann ich mit der BLOB-URL einen Vorteil erzielen?
Waqas Tahir
Sie können lesen , dies Ihre Antwort zu bekommen. Offensichtlich gibt es Vor- und Nachteile.
Robert
4
Sie mischen Objekt-URLs mit BLOBs. Die Objekt-URL ist ein Pseudoprotokoll, mit dem BLOBs als URI-Quelle verwendet werden können.
4
Diese Antwort weist einige erhebliche Mängel auf. Hauptsächlich, wie in einem vorherigen Kommentar erwähnt, werden einige sehr unterschiedliche Konzepte gemischt ... und dann zu einer unvollständigen und falschen Antwort komprimiert.
trs
2

Ich habe die Arbeitslösung geändert, um sowohl den Fall als auch das Hochladen von Videos und das Hochladen von Bildern zu behandeln. Ich hoffe, es wird einigen helfen.

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/

Pratap Dessai
quelle
1. Was ist der Zweck des Einrückens in Ihrem Code? Alle anderen verwenden Einrückungen, um die logische Struktur des Codes hervorzuheben. 2. Ihre JSFiddle macht nichts. Ich habe versucht, ein Bild und ein Video hochzuladen.
7vujy0f0hy