URL หยดคืออะไรและทำไมจึงใช้


350

ฉันมีปัญหามากมายกับ URL หยด

ฉันค้นหาsrcแท็กวิดีโอบน YouTube และพบว่าวิดีโอsrcเป็นเช่น:

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

ฉันเปิด blob URL ที่อยู่ในsrcวิดีโอมันทำให้เกิดข้อผิดพลาด ฉันไม่สามารถเปิดลิงก์ได้ แต่มันทำงานกับsrcแท็ก เป็นไปได้อย่างไร?

ที่ต้องการ:

  • URL หยดคืออะไร?
  • ทำไมถึงใช้งาน
  • ฉันสามารถสร้าง URL หยดของตัวเองบนเซิร์ฟเวอร์ได้หรือไม่?
  • หากคุณมีรายละเอียดเพิ่มเติมใด ๆ

2
นอกจากนี้stackoverflow.com/q/14952052/632951
Pacerier

3
เป็นหลักไม่อนุญาตให้เชื่อมโยงฮอต (เช่น youtube)
facepalm42

คำตอบ:


350

Blob URL (อ้างอิงW3Cชื่ออย่างเป็นทางการ) หรือ Object-URL (อ้างอิงMDNและชื่อเมธอด) ใช้กับBlobหรือวัตถุไฟล์

src = "blob: https: //crap.crap " ฉันเปิด URL ของ blob ที่อยู่ใน src ของวิดีโอมันมีข้อผิดพลาดและฉันไม่สามารถเปิดได้ แต่ทำงานกับแท็ก src ว่าเป็นไปได้อย่างไร

Blob URL สามารถสร้างได้ภายในเบราว์เซอร์เท่านั้น URL.createObjectURL()จะสร้างการอ้างอิงพิเศษไปยังวัตถุ Blob หรือไฟล์ซึ่งสามารถนำออกใช้ในURL.revokeObjectURL()ภายหลัง URL เหล่านี้สามารถใช้ได้ภายในเครื่องเดียวในเบราว์เซอร์เดียวและในเซสชันเดียวกัน (เช่นอายุการใช้งานของหน้า / เอกสาร)

URL หยดคืออะไร
ทำไมถึงใช้งาน

Blob URL / Object URL เป็นโปรโตคอลหลอกที่อนุญาตให้ใช้วัตถุ Blob และ File เป็นแหล่ง URL สำหรับสิ่งต่าง ๆ เช่นรูปภาพลิงก์ดาวน์โหลดข้อมูลไบนารีและอื่น ๆ

ตัวอย่างเช่นคุณไม่สามารถส่งอิมเมจวัตถุดิบ byte-data เพราะมันจะไม่รู้ว่าจะทำอย่างไรกับมัน มันต้องการตัวอย่างรูปภาพ (ซึ่งเป็นข้อมูลไบนารี) ที่จะโหลดผ่าน URL สิ่งนี้ใช้ได้กับทุกสิ่งที่ต้องการ URL เป็นแหล่งที่มา แทนที่จะอัปโหลดข้อมูลไบนารีจากนั้นให้บริการข้อมูลกลับผ่าน URL จะเป็นการดีกว่าหากใช้ขั้นตอนในพื้นที่พิเศษเพื่อให้สามารถเข้าถึงข้อมูลได้โดยตรงโดยไม่ต้องผ่านเซิร์ฟเวอร์

นอกจากนี้ยังเป็นทางเลือกที่ดีกว่าที่จะข้อมูล URI ซึ่งเป็นสตริงเข้ารหัสเป็นฐาน-64 ปัญหาของ Data-URI คือถ่านแต่ละตัวใช้เวลาสองไบต์ใน JavaScript ยิ่งไปกว่านั้น 33% จะถูกเพิ่มเนื่องจากการเข้ารหัส Base-64 Blobs เป็นไบนารี่ไบท์อาร์เรย์ที่ไม่มีค่าใช้จ่ายที่สำคัญเช่นเดียวกับ Data-URI ซึ่งทำให้เร็วขึ้นและเล็กลงในการจัดการ

ฉันสามารถสร้าง URL ของตัวเองบนเซิร์ฟเวอร์ได้หรือไม่?

ไม่ได้ URL ของ Blob / URL วัตถุสามารถทำได้ภายในเบราว์เซอร์เท่านั้น คุณสามารถสร้าง Blobs และรับวัตถุไฟล์ผ่าน File Reader API ได้แม้ว่า 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-browser เพื่อใช้

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

19
ในช่วง 6 ชั่วโมงที่ผ่านมาฉันพยายามทำให้ PHP เปลี่ยน URL วัตถุที่ส่งผ่านจาก AJAX ไปเป็นไฟล์รูปภาพ .. มันไม่ได้จนกว่าฉันจะอ่านคำอธิบายของคุณว่าฉันรู้ว่าทำไมมันถึงไม่เขียนข้อมูลใด ๆ ลงในไฟล์ .. คำอธิบายที่กระชับและละเอียดถี่ถ้วนของคุณได้ยุติความทุกข์ยากของฉัน ขอบคุณ.
Partack

4
@ K3N เป็นไปได้หรือไม่ที่จะได้รับแหล่งที่มาที่แท้จริงของ blob URL แทนที่จะเป็น URL ที่สร้างขึ้น Nest cam สร้าง URL หยดเพื่อป้องกันไม่ให้คนบันทึกกล้องของตัวเอง
Alex Kwitny

4
ตรัสรู้สำหรับฉัน "หยดก็หมายความว่าวัตถุขนาดใหญ่ไบนารี"
canbax

6
เป็นไปได้หรือไม่ที่จะดึงเนื้อหาของวัตถุ blob / file และดาวน์โหลดสิ่งที่มันเป็น (ภาพหรือวิดีโอ)?
DFSFOT

4
สิ่งนี้อาจเกี่ยวข้องกับผู้คนที่สงสัยว่าจะดาวน์โหลดวิดีโอ blob ได้อย่างไร: stackoverflow.com/q/42901942/1530508
ApproachingDarknessFish

10

ฟังก์ชัน Javascript นี้มีวัตถุประสงค์เพื่อแสดงความแตกต่างระหว่างBlob File API และ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 URL.createObjectURLได้รับการยอมรับได้ทันทีโดยเบราว์เซอร์ที่จะทำการดาวน์โหลดไฟล์ที่สร้างขึ้นโดยตรงโดยใช้ไฟล์ของ API

ในelseมันเป็นไปได้ที่จะเห็นผลลัพธ์เดียวกันที่ได้รับผ่านhrefองค์ประกอบบวก Data API แต่มีข้อ จำกัด หลายประการที่ Blob API ไม่ได้


1
คุณสามารถปรับตัวนี้เพื่อบันทึกวิดีโอจากทวีตได้หรือไม่?
logicbloke

3

URL หยดคืออะไร ทำไมถึงใช้งาน

BLOB เป็นเพียงลำดับไบต์ เบราว์เซอร์รับรู้ว่ามันเป็นไบต์ มันถูกใช้เพื่อรับกระแสข้อมูลไบต์จากแหล่งที่มา

วัตถุ Blob แสดงวัตถุคล้ายไฟล์ข้อมูลดิบที่ไม่เปลี่ยนรูป Blobs แสดงข้อมูลที่ไม่จำเป็นต้องอยู่ในรูปแบบของ JavaScript ส่วนต่อประสานไฟล์นั้นขึ้นอยู่กับ Blob ซึ่งสืบทอดการทำงานของ Blob และขยายไปยังรองรับไฟล์ในระบบของผู้ใช้

ฉันสามารถสร้าง URL ของตัวเองบนเซิร์ฟเวอร์ได้หรือไม่?

ใช่คุณสามารถมีวิธีที่เซิร์ฟเวอร์ทำเช่นลองhttp://php.net/manual/en/function.ibase-blob-echo.php

อ่านเพิ่มเติมได้ที่


2
ฉันจะได้รับประโยชน์ใด ๆ จากการใช้ BLOB url หรือไม่
Waqas Tahir

คุณสามารถอ่านสิ่งนี้เพื่อรับคำตอบของคุณ เห็นได้ชัดว่ามีข้อดีและข้อเสีย
Robert

4
คุณกำลังผสม Object-URL กับ BLOB Object-URL เป็นโปรโตคอลหลอกที่อนุญาตให้ BLOB ใช้เป็นแหล่งที่มาของ URI

4
มีข้อบกพร่องบางอย่างที่สำคัญกับคำตอบนี้ ส่วนใหญ่ตามที่ระบุไว้ในความคิดเห็นก่อนหน้าบางแนวคิดที่แตกต่างกันมากผสม ... แล้วบีบอัดเป็นคำตอบที่ไม่สมบูรณ์และไม่ถูกต้อง
trs

2

ฉันได้แก้ไขวิธีการทำงานเพื่อจัดการกับทั้งสองกรณี .. เมื่อมีการอัปโหลดวิดีโอและเมื่อมีการอัปโหลดภาพ .. หวังว่ามันจะช่วยได้บ้าง

HTML

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

จาวาสคริ

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.จุดประสงค์ของการเยื้องในรหัสของคุณคืออะไร ทุกคนใช้การเยื้องเพื่อเน้นโครงสร้างตรรกะของรหัส 2. JSFiddle ของคุณไม่ทำอะไรเลย ฉันพยายามอัพโหลดภาพและวิดีโอ
7vujy0f0hy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.