浅谈JavaScript中Blob对象

0 阅读4分钟

浅谈JavaScript中Blob对象

大纲

本文大纲如下,都了解的同学可以跳过啦!

概念

Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。

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

上述内容来自于 MDN-Blob[1]

构造函数

Blob() 构造函数返回一个新的 Blob 对象。

语法
new Blob(blobParts);
new Blob(blobParts, options);
参数
  • blobParts
    一个可迭代对象,比如 Array,包含 ArrayBuffer、TypedArray、DataView、Blob、字符串或者任意这些元素的混合,这些元素将会被放入 Blob 中。字符串应该是格式良好的 Unicode。
  • options
    一个对象,包含以下属性:
    type:可选。一个MIME格式字符串,表示 Blob 的内容类型。
    endings:可选。一个枚举值,表示 Blob 中数据的处理方式。如果数据是文本,那么如何解释其中的换行符(\n)。默认值 transparent 会将换行符复制到 blob 中而不会改变它们。要将换行符转换为主机系统的本地约定,请指定值 native。

Blob实例属性

  • size
    只读。 Blob 对象的字节数。
  • type
    只读。 Blob 对象的 MIME 类型。

Blob实例方法

  • slice()
    返回一个新的 Blob 对象,该对象包含源 Blob 对象的指定部分。
  • stream()
    返回一个包含 Blob 中数据的可读流(ReadableStream)。
  • text()
    返回一个 Promise,该 Promise 会在 Blob 中包含的文本完成读取后 resolve。
  • arrayBuffer()
    返回一个 Promise,该 Promise 会在 Blob 中包含的 ArrayBuffer 读取后 resolve。
  • bytes()
    返回一个 Promise,该 Promise 会在 Blob 中包含的Uint8Array读取后 resolve。支持该方法的浏览器较少。
let blob = new Blob(["你好,世界!"], {type"text/plain"});
// 输出:Blob {size: 18, type: "text/plain"}
// 一个中文字占三个字节,所以 size 为 18
console.log(blob)
// slice() 方法返回一个新的 Blob 对象,该对象包含从 start 到 end(不包括 end 本身)的所有内容。
let newBlob = blob.slice(06);
// text() 方法返回一个 Promise,为包含 Blob 内容的字符串。
// 输出:你好
newBlob.text().then(txt => console.log(txt))
// bytes() 方法返回一个Promise,包含 Blob 内容的 Uint8Array。目前Chrome浏览器不支持此方法。
newBlob?.bytes && newBlob.bytes().then(bytes => console.log(bytes))
// arrayBuffer() 方法返回一个 Promise,包含 Blob 内容的 ArrayBuffer。
newBlob.arrayBuffer().then(buffer => {
    // ArrayBuffer [228,189,160,229,165,189]
    console.log(buffer);
    // 输出:你好
    console.log(new TextDecoder().decode(buffer))
})
async function readBlobByStream(){
    // stream() 方法返回一个包含 Blob 内容的 ReadableStream 对象。以下代码用迭代的方式读取 ReadableStream 内容。
    for await (let chunk of newBlob.stream()){
        // Uint8Array [228,189,160,229,165,189]
        console.log('chunk',chunk);
        // 输出:你好
        console.log('chunk.text',new TextDecoder().decode(chunk));
    }
}
readBlobByStream();

获取及创建

上述代码已经展示了通过构造函数及Blob.slice对象创建Blob对象,下面介绍通过fetch获取远程文件创建Blob对象。

通过fetch获取远程文件创建

fetch API 可以很方便的设置响应,以blob方式返回。

fetch('./demo.txt').then(response => response.blob()).then(blob => {
        // Blob {size: 20, type: "text/plain"}
        console.log(blob);
        // 输出:你好,世界!
        blob.text().then(txt => console.log(txt))
    });

类似的,也可以通过设置XMLHttpRequest的responseType设置为blob,也可以获取blob对象。其他ajax库可以参考文档设置。

从Blob中提取数据

上文展示了通过Blob.text()方法获取数据,下面介绍通过FileReader对象或Response对象来读取。

FileReader

FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。

    let blob = new Blob(["你好,世界!"], {type"text/plain"});
    let reader = new FileReader();
    reader.onload = function(e) {
        // 输出:你好,世界!
        console.log(reader.result);
    }
    reader.readAsText(blob);

Response

利用blob手动构建一个 Response 对象,通过Response也可以读取。

    let blob = new Blob(["你好,世界!"], {type"text/plain"});
    let response = new Response(blob);
    // 输出:你好,世界!
    response.text().then(txt => console.log(txt));

Blob URLs

Blob URLs(Blob URLs)是一种特殊类型的 URL,用于访问 Blob 对象。

如果用浏览器打开本地文件,你会发现 url 是以 “file://“ 开头的, 一个 file:// URL 引用了本地文件系统中的一个真实文件。

类似的,一个 blob:// URL 指向一个Blob对象。

几乎所有可以使用 urls 的地方都可以使用 blob:// URLs。

我们需要用createObjectURL对象来为一个blob创建一个url。

URL.createObjectURL()静态方法会创建一个DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的document绑定。这个新的URL 对象表示指定的File对象或Blob对象。

    fetch('./assets/363.png').then(response=>response.blob()).then(blob=>{
        let url = URL.createObjectURL(blob);
        let img = document.createElement('img');
        img.src = url;
        img.onload=()=>{
            // 释放内存,养成一个好习惯,用完就释放掉。当然,网页销毁时,也会自动释放,但为了避免内存泄漏,还是建议用完就释放。
            URL.revokeObjectURL(url);
        }
        document.body.appendChild(img)
    })
引用链接

[1] MDN-Blob: developer.mozilla.org/zh-CN/docs/…