什么是blob URL以及为何使用它?

Waq*_*hir 272 html5-video bloburls

我对blob URL有很多问题.

src在YouTube上搜索视频标签,我发现该视频src如下:

src="blob:https://crap.crap"
Run Code Online (Sandbox Code Playgroud)

我打开了src视频中的blob URL,它给出了一个错误,我无法打开,但正在处理src标签.这怎么可能?

要求:

  • 什么是blob网址?
  • 为什么用它?
  • 我可以在服务器上创建自己的blob URL吗?
  • 如果您有任何其他详细信息

小智 271

Blob URL(ref W3C,官方名称)或Object-URLs(ref.MDN和方法名称)与BlobFile对象一起使用.

src ="blob:https://crap.crap "我打开了视频src中的blob网址,它给出了一个错误,我无法打开但是正在使用src标签怎么可能?

Blob URL只能由浏览器在内部生成.URL.createObjectURL()将创建一个特殊的引用Blob或File对象,以后可以使用它URL.revokeObjectURL().这些URL只能在浏览器的单个实例中本地使用,并且可以在同一会话中使用(即页面/文档的生命周期).

什么是blob网址?
为什么用它?

Blob URL/Object URL是一种伪协议,允许Blob和File对象用作图像,下载二进制数据链接等URL源.

例如,您无法处理Image对象原始字节数据,因为它不知道如何处理它.例如,它需要通过URL加载图像(二进制数据).这适用于需要URL作为源的任何内容.而不是上传二进制数据,然后通过URL提供服务,最好使用额外的本地步骤,以便能够直接访问数据,而无需通过服务器.

它也是Data-URI的更好替代品,它是编码为Base-64的字符串.Data-URI的问题是每个char在JavaScript中占用两个字节.最重要的是,由于Base-64编码,添加了33%.Blob是纯二进制字节数组,它不像Data-URI那样具有任何显着的开销,这使得它们更快更小.

我可以在服务器上创建自己的blob网址吗?

不,Blob URL /对象URL只能在浏览器内部进行.您可以通过File Reader API创建Blob并获取File对象,尽管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
Run Code Online (Sandbox Code Playgroud)

请注意,URL可以在webkit浏览器中添加前缀,因此请使用:

var url = (URL || webkitURL).createObjectURL(...);
Run Code Online (Sandbox Code Playgroud)

  • 在过去的6个小时里,我一直在尝试让PHP将从AJAX传递的对象URL转换为图像文件.直到我读到你的解释,我才意识到为什么它没有写任何数据到文件..你简明扼要的解释已经结束了我的痛苦.谢谢. (10认同)
  • 这可能与想知道如何下载 blob 视频的人相关:/sf/ask/3003135971/ (5认同)
  • @ K3N是否可以获取blob URL的真正来源而不是生成的URL?Nest cam生成blob URL以防止人们录制自己的摄像头 (4认同)
  • 是否可以检索Blob /文件对象的内容并下载其内容(图像或视频)? (3认同)
  • 在 OP 的原始上下文中,为什么 YouTube 嵌入播放器会使用 `blob:` URL?我假设浏览器将视频流下载为二进制文件,然后使用 blob URL 创建视频元素。这比让视频元素直接下载 URL 有什么好处呢? (3认同)
  • @Jeff YouTube 不使用 Blob,他们使用 [MediaSource API](https://developer.mozilla.org/en-US/docs/Web/API/MediaSource/),它也由 `blob 指向: //` 网址。不幸的是,这个答案完全忽略了这一点,尽管这是OP中被问到的问题。 (3认同)
  • 对我的启示“ BLOB只是意味着二进制大对象” (2认同)
  • 抱歉...我需要更好的背景来回答这个问题。我在 MacOS 文件的“源起源扩展属性”中得到这些“blob:http://”URL - 告诉我“文件来自哪里”。我试图理解“什么是 blob url”,但这个答案在我的上下文中没有足够的帮助。顺便说一句 - 下载的文件 - 不是在本地创建的,而是真正从某个服务器下载的。 (2认同)

lor*_*isi 11

这个 Javascript 函数旨在显示Blob文件 API 和数据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));
Run Code Online (Sandbox Code Playgroud)

该函数被称为像saveAsFile('out.json', jsonString);。它将创建一个 ByteStream 立即被浏览器识别,它将使用 File API 直接下载生成的文件URL.createObjectURL

在 中else,可以看到通过href元素加上数据 API获得的相同结果,但这有一些 Blob API 没有的限制。

  • 你能修改这个来保存推文中的视频吗? (2认同)

Rob*_*ert 6

OP问:

什么是 blob URL?为什么使用它?

Blob 只是字节序列。浏览器将 Blob 识别为字节流。它用于从源获取字节流。根据Mozilla 的文档

Blob 对象表示不可变的原始数据的类文件对象。Blob 表示不一定采用 JavaScript 原生格式的数据。File接口基于Blob,继承了blob功能并将其扩展以支持用户系统上的文件。

OP问:

我可以在服务器上创建自己的 blob url 吗?

是的,您可以有多种方法,例如尝试http://php.net/manual/en/function.ibase-blob-echo.php

在这里阅读更多内容:

  • 您正在将对象 URL 与 BLOB 混合在一起。Object-URL 是一个伪协议,允许将 BLOB 用作 URI 源。 (7认同)
  • 这个答案存在一些重大缺陷。主要正如之前的评论中指出的那样,一些非常不同的概念被混合在一起......然后压缩成一个不完整且不正确的答案。 (5认同)
  • 我假设当询问“我可以在服务器上创建自己的 blob URL 吗?”时,OP 希望能够将 URL 传递到浏览器,并让它下载 blob 数据。**你不能这样做**,并且你链接到的 PHP 页面是关于数据库 BLOB 功能的,这与浏览器/javascript BLOB 根本不同。 (5认同)
  • 使用 BLOB url 可以获得什么好处吗? (2认同)

小智 6

我修改了工作解决方案来处理这两种情况..上传视频和上传图像时..希望它会对一些人有所帮助。

超文本标记语言

<input type="file" id="fileInput">
<div> duration: <span id='sp'></span><div>
Run Code Online (Sandbox Code Playgroud)

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

};
Run Code Online (Sandbox Code Playgroud)

jsFiddle 网址

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

  • @7vujy0f0hy — 它向控制台输出有关上传文件的各种信息。您希望它做什么,将其上传到某个地方?这有点难以证明。作者做得很合理——你必须查看代码才能知道它在做什么。 (6认同)
  • 这如何回答*什么是 blob URL 的原始问题?为什么使用它?* (3认同)