【问题标题】:What is a blob URL and why it is used?什么是 blob URL,为什么使用它?
【发布时间】:2015-09-01 02:15:30
【问题描述】:

我在使用 blob URL 时遇到了很多问题。

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

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

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

要求:

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

【问题讨论】:

  • 基本上不允许盗链。 (如 youtube)
  • 暗示其目的是“禁止盗链”有点虚伪。相反,它允许在浏览器本身内创建临时内容。如果临时内容来自一些下载的内容,例如 Youtube,那么您仍然欢迎直接热链接 that 源,但可能需要您使用 JS 调试器来查找它。 (当然,如果您随后使用该 URL 下载非临时副本,则您的访问许可或您在版权法下的权利可能不允许这样做。)

标签: html5-video bloburls


【解决方案1】:

Blob URL(参考 W3C,正式名称)或 Object-URL(参考 MDN 和方法名称)与 BlobFile 对象一起使用。

src="blob:https://crap.crap" 我打开了 src 中的 blob url 视频出现错误,我无法打开,但正在使用 src 标记怎么可能?

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

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

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

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

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

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

不可以,Blob URL/对象 URL 只能在浏览器内部创建。您可以通过 File Reader API 创建 Blob 并获取 File 对象,尽管 BLOB 仅表示二进制大对象并且存储为字节数组。客户端可以请求将数据作为 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-browsers 中作为前缀,所以使用:

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

【讨论】:

  • @K3N 是否可以获得blob URL的真实来源而不是生成的URL? Nest cam 生成一个 blob URL 以防止人们录制自己的相机
  • 对我的启示“BLOB 就是二进制大对象”
  • 是否可以检索 blob/文件对象的内容并下载它的任何内容(图像或视频)?
  • 在 OP 的原始上下文中,为什么 YouTube 嵌入播放器会使用 blob: URL?我假设浏览器将视频流下载为二进制文件,然后使用 blob URL 创建视频元素。有什么比让视频元素直接下载 URL 更好?
  • 这可能与想知道如何下载 blob 视频的人有关:stackoverflow.com/q/42901942/1530508
【解决方案2】:

此 Javascript 函数支持显示 Blob 文件 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,该浏览器将使用 File API URL.createObjectURL 直接下载生成的文件。

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

【讨论】:

  • 你能修改它来保存推文中的视频吗?
  • 当我将.href 设置为downloadLink.href="blob:https://www.wmur.com/aa14dc0d-c44c-4072-b918-bff92d26b9b7" 并调用downloadLink.click() 时,它会给我一个错误Network Error
  • @Chloe 在浏览器支持Blob 对象的情况下,您将使用它来存储文件的二进制化内容,但此函数无论如何会将其保存为可下载文件,但使用 api createObjectURL;所以没有必要更改href,除非你的目标是做一些不同的事情。
【解决方案3】:

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

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 网址

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

【讨论】:

  • 1. 在您的代码中缩进的目的是什么?其他人都使用缩进来突出代码的逻辑结构。 2. 你的 JSFiddle 什么都不做。我尝试上传图片和视频。
  • @7vujy0f0hy — 它向控制台输出有关上传文件的各种信息。你期望它做什么,把它上传到某个地方?这有点难以证明。作者做了一个合理的工作——你必须查看代码才能看到它在做什么。
【解决方案4】:

OP 询问:

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

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

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

OP 询问:

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

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

在这里阅读更多:

【讨论】:

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

blob url 用于显示用户上传的文件,但它们还有许多其他用途,例如它可以用于安全文件显示,例如在不下载扩展程序的情况下获取 YouTube 视频有点困难。但是,它们可能是更多的答案。我的研究主要是我使用 Inspect 尝试获取 YouTube 视频和 online article

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-08
    • 2011-10-31
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2017-01-10
    相关资源
    最近更新 更多