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

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

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

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

我打开视频src中的blob URL,它出现了错误。我不能打开这个链接,但它在src标签下是有效的。这怎么可能呢?

要求。

  • 什么是blob URL?
  • 为什么要使用它?
  • 我可以在服务器上制作自己的blob URL吗?
  • 如果你有任何其他细节
对该问题的评论 (3)
解决办法

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

src="blob:https://crap.crap" 我打开了blob网址,该网址在src的 视频时出现了错误,我无法打开,但却在使用src 标签,这怎么可能呢?

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

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

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

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

这也是对Data-URI的一个更好的选择,Data-URI是以Base-64编码的字符串。Data-URI的问题是,每个字符在JavaScript中需要两个字节。除此之外,由于Base-64编码,还增加了33%。Blobs是纯粹的二进制字节数,它不像Data-URI那样有任何明显的开销,这使得它们处理起来更快、更小。

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

不能,Blob URL/Object URLs只能在浏览器内部制作。您可以通过文件阅读器API制作Blob并获取文件对象,尽管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浏览器中可能有前缀,所以使用。

var url = (URL || webkitURL).createObjectURL(...);
评论(14)

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

BLOB只是一个字节序列。浏览器将其识别为字节流。它被用来从源头获取字节流。

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

*我可以在服务器上制作自己的blob网址吗?

是的,你可以这样做,有很多方法可以做到,例如,可以试试http://php.net/manual/en/function.ibase-blob-echo.php

阅读更多信息

评论(4)

这个Javascript函数旨在展示Blob文件API和DataAPI之间的区别,以便在客户端浏览器中下载一个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,它将使用文件APIURL.createObjectURL直接下载生成的文件。

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

评论(1)

我已经修改了工作方案来处理这两种情况。 当视频被上传和当图像被上传。 希望对大家有所帮助。

html <输入类型="文件&quot。 id="fileInput"> <div&gt.id="文件输入 持续时间。 <div&gt。

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('image');
                            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)