Apa itu URL gumpalan dan mengapa itu digunakan?

348

Saya memiliki banyak masalah dengan URL gumpalan.

Saya sedang mencari srctag video di YouTube dan saya menemukan bahwa videonya srcseperti:

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

Saya membuka URL gumpalan yang ada di srcvideo itu memberikan kesalahan. Saya tidak dapat membuka tautan, tetapi itu bekerja dengan srctag. Bagaimana ini mungkin?

Persyaratan:

  • Apa itu URL gumpalan?
  • Kenapa digunakan?
  • Bisakah saya membuat URL gumpalan saya sendiri di server?
  • Jika Anda memiliki detail tambahan
Waqas Tahir
sumber
3
Pada dasarnya tidak mengizinkan hotlinking. (seperti youtube)
facepalm42

Jawaban:

349

Blob URL (ref W3C , nama resmi) atau Object-URLs (ref. MDN dan nama metode) digunakan dengan objek Blob atau File .

src = "blob: https: //crap.crap " Saya membuka url blob yang ada di src video itu memberikan kesalahan dan saya tidak bisa membuka tetapi bekerja dengan tag src bagaimana mungkin?

Blob URL hanya dapat dibuat secara internal oleh browser. URL.createObjectURL()akan membuat referensi khusus ke objek Blob atau File yang nantinya dapat dirilis menggunakan URL.revokeObjectURL(). URL ini hanya dapat digunakan secara lokal dalam satu instance browser dan dalam sesi yang sama (mis. Masa pakai halaman / dokumen).

Apa itu url gumpalan?
Kenapa digunakan?

Blob URL / Object URL adalah protokol semu untuk memungkinkan objek Blob dan File digunakan sebagai sumber URL untuk hal-hal seperti gambar, tautan unduhan untuk data biner dan sebagainya.

Misalnya, Anda tidak dapat menyerahkan objek gambar byte-data mentah karena tidak akan tahu apa yang harus dilakukan dengannya. Misalnya diperlukan gambar (yang merupakan data biner) untuk dimuat melalui URL. Ini berlaku untuk apa pun yang memerlukan URL sebagai sumber. Daripada mengunggah data biner, kemudian menyajikannya kembali melalui URL, lebih baik menggunakan langkah lokal tambahan untuk dapat mengakses data secara langsung tanpa melalui server.

Ini juga merupakan alternatif yang lebih baik untuk Data-URI yang string dikodekan sebagai Base-64 . Masalah dengan Data-URI adalah bahwa setiap karakter mengambil dua byte dalam JavaScript. Selain itu, 33% ditambahkan karena pengkodean Base-64. Blob adalah byte-array binary murni yang tidak memiliki overhead signifikan seperti Data-URI, yang membuatnya lebih cepat dan lebih kecil untuk ditangani.

Bisakah saya membuat url gumpalan saya sendiri di server?

Tidak, Blob URLs / Object URLs hanya dapat dibuat secara internal di browser. Anda dapat membuat Blob dan mendapatkan objek File melalui File Reader API, meskipun BLOB hanya berarti Binary Large OBject dan disimpan sebagai byte-array. Klien dapat meminta data untuk dikirim sebagai ArrayBuffer atau sebagai Blob. Server harus mengirim data sebagai data biner murni. Basis data sering menggunakan Blob untuk menggambarkan objek biner juga, dan pada dasarnya kita berbicara tentang byte-array.

jika Anda memiliki detail tambahan

Anda perlu merangkum data biner sebagai objek BLOB, kemudian gunakan URL.createObjectURL()untuk menghasilkan URL lokal untuk itu:

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

Catatan yang URLmungkin diawali di browser webkit, jadi gunakan:

var url = (URL || webkitURL).createObjectURL(...);
Bakudan
sumber
19
Selama 6 jam terakhir saya telah mencoba membuat PHP mengubah URL objek yang dilewatkan dari AJAX menjadi file gambar .. Tidak sampai saya membaca penjelasan Anda bahwa saya menyadari mengapa tidak menulis data apa pun ke file .. Penjelasan singkat dan menyeluruh Anda telah mengakhiri kesengsaraan saya. Terima kasih.
Partack
4
@ K3N apakah mungkin untuk mendapatkan sumber sebenarnya dari gumpalan URL daripada URL yang dihasilkan? Nest cam menghasilkan URL gumpalan untuk mencegah orang merekam kamera mereka sendiri
Alex Kwitny
4
pencerahan bagi saya "BLOB hanya berarti Binary Large OBject"
canbax
6
Apakah mungkin untuk mengambil isi objek gumpalan / file dan mengunduh apa pun itu (gambar atau video)?
DFSFOT
4
Ini mungkin berkaitan dengan orang-orang yang bertanya-tanya bagaimana cara mengunduh video gumpalan: stackoverflow.com/q/42901942/1530508
ApproachingDarknessFish
10

Fungsi Javascript ini bertujuan untuk menunjukkan perbedaan antara Blob File API dan Data API untuk mengunduh file JSON di browser klien:

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

Fungsi ini disebut seperti saveAsFile('out.json', jsonString);. Ini akan membuat ByteStream segera dikenali oleh browser yang akan mengunduh file yang dihasilkan secara langsung menggunakan File API URL.createObjectURL.

Dalam else, dimungkinkan untuk melihat hasil yang sama yang diperoleh melalui hrefelemen plus API Data, tetapi ini memiliki beberapa keterbatasan yang tidak dimiliki API Blob.

loretoparisi
sumber
1
Bisakah Anda mengadaptasi ini untuk menyimpan video dari tweet?
logicbloke
3

Apa itu url gumpalan? Kenapa digunakan?

BLOB hanyalah urutan byte. Browser mengenalinya sebagai aliran byte. Ini digunakan untuk mendapatkan aliran byte dari sumber.

Objek Blob mewakili objek seperti file dari data mentah yang tidak dapat diubah. Blob mewakili data yang tidak harus dalam format JavaScript-asli. Antarmuka File didasarkan pada Blob, mewarisi fungsi blob dan memperluasnya untuk mendukung file pada sistem pengguna.

Bisakah saya membuat url gumpalan saya sendiri di server?

Ya Anda bisa ada cara serveral untuk melakukannya misalnya coba http://php.net/manual/en/function.ibase-blob-echo.php

Baca lebih lanjut

Robert
sumber
2
Bisakah saya mendapatkan manfaat dengan menggunakan url BLOB?
Waqas Tahir
Anda dapat membaca ini untuk mendapatkan jawaban Anda. Jelas ada pro dan kontra.
Robert
4
Anda mencampur Object-URL dengan BLOB. Object-URL adalah protokol pseudo untuk memungkinkan BLOB digunakan sebagai sumber URI.
4
Ada beberapa kelemahan signifikan dengan jawaban ini. Terutama seperti yang ditunjukkan dalam komentar sebelumnya beberapa konsep yang sangat berbeda dicampurkan ... dan kemudian dikompres menjadi jawaban yang tidak lengkap dan salah.
trs
2

Saya telah memodifikasi solusi kerja untuk menangani kedua kasus ini .. saat video diunggah dan ketika gambar diunggah .. semoga akan membantu.

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
sumber
1. Apa tujuan lekukan dalam kode Anda? Semua orang menggunakan indentasi untuk menyoroti struktur logis dari kode. 2. JSFiddle Anda tidak melakukan apa pun. Saya mencoba mengunggah gambar dan video.
7vujy0f0hy