什么是 blob URL 以及使用它的原因

  • 本文关键字:blob URL bloburls
  • 更新时间 :
  • 英文 :


我在blob URL时遇到问题。

我在YouTube上搜索video标签的src,发现视频src是这样的:

src="blob:https://video_url"

我打开了视频srcblob URL,但它给出了错误。我无法打开链接,但它正在使用src标签。这怎么可能?

我有几个问题:

  • 什么是blob网址?
  • 为什么使用它?
  • 我可以在服务器上创建自己的blob URL 吗?

有关blob URL 的任何其他详细信息也会有所帮助。

Blob URL(ref

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

我打开了视频srcblob URL,但它给出了错误。我无法打开链接,但它正在使用src标签。这怎么可能?

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

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

Blob URL/对象 URL

是一种伪协议,允许将 Blob 和文件对象用作图像、二进制数据的下载链接等内容的 URL 源。

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

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

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

不可以,Blob URL/对象 URL 只能在浏览器中内部创建。您可以通过File Reader API创建Blob并获取File对象,尽管BLOB仅表示二进制大型OBject并存储为字节数组。客户端可以请求将数据作为 ArrayBuffer 或 Blob 发送。服务器应将数据作为纯二进制数据发送。数据库也经常使用 Blob 来描述二进制对象,本质上我们基本上谈论的是字节数组。

有关blob URL 的任何其他详细信息也会有所帮助。

您需要将二进制数据封装为 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

此 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));

该函数的调用方式与 saveAsFile('out.json', jsonString); 类似。它将创建一个浏览器立即识别的字节流,该字节流将使用文件API直接下载生成的文件URL.createObjectURL

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

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

.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/

OP 问:

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

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

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

OP问:

是否可以在服务器上创建自己的 Blob URL?

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

在这里阅读更多内容:

  • https://developer.mozilla.org/en-US/docs/Web/API/Blob
  • http://www.w3.org/TR/FileAPI/#dfn-Blob
  • https://url.spec.whatwg.org/#urls

blob URL 用于显示用户上传的文件,但它们还有许多其他用途,例如它可以用于安全文件显示,例如在不下载扩展名的情况下将 YouTube 视频作为视频文件获取有点困难。但是,它们可能是更多的答案。我的研究主要是我使用检查来尝试获取YouTube视频和在线文章。

blob url 的另一个用例是从服务器加载资源,应用黑客,然后告诉浏览器解释它们。

一个这样的例子是加载模板文件甚至 scss 文件。

下面是 scss 示例:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.11.1/sass.sync.min.js"></script>
function loadCSS(text) {
    const head = document.getElementsByTagName('head')[0]
    const style = document.createElement('link')
    const css = new Blob([text], {type: 'text/css'})
    style.href = window.URL.createObjectURL(css)
    style.type = 'text/css'
    style.rel = 'stylesheet'
    head.append(style)
}
fetch('/style.scss').then(res => res.text()).then(sass => {
  Sass.compile(sass, ({text}) => loadCSS(text))
})   

现在,您可以将Sass.compile换成您喜欢的任何类型的转换函数。

Blob URL 以这种方式保持 DOM 结构干净。

我相信现在你已经有了答案,所以这只是你可以用它做的另外一件事。

最新更新