Blob介绍
工作中有时会遇到文件下载的需求,比如下载Excel或者别的文件,这时候就会遇到Blob类型。百度下就能找到相关示例将blob文件流转换成相关文件,那么在完成该功能时有没有想过blob文件流是什么,blob还有什么用途?深究下不仅能加深blob的理解,还能拓展知识面,触类旁通。
今天介绍内容如下:
1、Blob是什么
2、Blob API介绍
3、Blob使用场景
一、Blob是什么
1.1、Blob(Binary Large Object)表示二进制类型的大对象。在数据库管理系统中,将二进制数据存储为一个单一个体的集合。Blob 通常是影像、声音或多媒体文件。在 JavaScript 中 Blob 类型的对象表示不可变的类似文件对象的原始数据。 为了更直观的感受 Blob 对象,我们先来使用 Blob 构造函数,创建一个 myBlob 对象,具体如下图所示:
如你所见,myBlob 对象含有两个属性:size 和 type。其中 size 属性用于表示数据的大小(以字节为单位),type 是 MIME 类型的字符串。Blob 表示的不一定是JavaScript 原生格式的数据。比如 File 接口基于 Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件
Blob 由一个可选的字符串 type(通常是 MIME 类型)和 blobParts 组成:
MIME是是一种标准,用来表示文档、文件或字节流的性质和格式,多用途互联网邮件扩展类型,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。如果配置不正确,浏览器可能会曲解文件内容,网站将无法正常工作,并且下载的文件也会被错误处理
1.2 构造函数
blob是构造函数,语法如下:
let blobObj = new Blob(blobParts,options);
相关的参数说明如下:
- blobParts:它是一个由 ArrayBuffer,ArrayBufferView,Blob,DOMString 等对象构成的数组。DOMStrings 会被编码为 UTF-8。
- options:一个可选的对象,包含以下两个属性:
- type —— 默认值为 "",它代表了将会被放入到 blob 中的数组内容的 MIME 类型。
- endings —— 默认值为 "transparent",用于指定包含行结束符 \n 的字符串如何被写入。 它是以下两个值中的一个: "native",代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 "transparent",代表会保持 blob 中保存的结束符不变。
1 // 示例一:从字符串创建 Blob 2 let myBlobParts = ['<html><h2>Hello Semlinker</h2></html>']; // 注意,这里是数组 3 let myBlob = new Blob(myBlobParts, {type : 'text/html', endings: "transparent"}); // the blob 4 console.log('myBlob',myBlob) 5 console.log(myBlob.size + " bytes size"); 6 console.log(myBlob.type + " is the type");
二、Blob 类的属性和方法:
属性:
size(只读):表示 Blob 对象中所包含数据的大小(以字节为单位)。
type(只读):一个字符串,表明该 Blob 对象所包含数据的 MIME 类型。如果类型未知,则该值为空字符串。
方法:
- slice([start[, end[, contentType]]]):返回一个新的 Blob 对象,包含了源 Blob 对象中指定范围内的数据。
- stream():返回一个能读取 blob 内容的 ReadableStream。
- text():返回一个 Promise 对象且包含 blob 所有内容的 UTF-8 格式的 USVString。
- arrayBuffer():返回一个 Promise 对象且包含 blob 所有内容的二进制格式的 ArrayBuffer。
这里我们需要注意的是,Blob 对象是不可改变的。我们不能直接在一个 Blob 中更改数据,但是我们可以对一个 Blob 进行分割,从其中创建新的 Blob 对象,将它们混合到一个新的 Blob 中。这种行为类似于 JavaScript 字符串:我们无法更改字符串中的字符,但可以创建新的更正后的字符串。
三、blob使用场景
3.1、分片上传
File 对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的上下文中。所以针对大文件传输的场景,我们可以使用 slice 方法对大文件进行切割,然后分片进行上传,具体示例如下:
1 const file = new File(["a".repeat(1000000)], "test.txt"); 2 3 const chunkSize = 40000; 4 const url = "https://httpbin.org/post"; 5 6 async function chunkedUpload() { 7 for (let start = 0; start < file.size; start += chunkSize) { 8 const chunk = file.slice(start, start + chunkSize + 1); 9 const fd = new FormData(); 10 fd.append("data", chunk); 11 12 await fetch(url, { method: "post", body: fd }).then((res) => 13 res.text() 14 ); 15 } 16 }
3.2、 Blob 用作 URL
浏览器内部为每个通过 URL.createObjectURL 生成的 URL 存储了一个 URL → Blob 映射。因此,此类 URL 较短,但可以访问 Blob。生成的 URL 仅在当前文档打开的状态下才有效。它允许引用 、 中的 Blob,但如果你访问的 Blob URL 不再存在,则会从浏览器中收到 404 错误。
1 //伪代码,下载Excel 2 const downloadBlob = (url, callback) => { 3 const xhr = new XMLHttpRequest() 4 xhr.open('GET', url) 5 xhr.responseType = 'blob'//设置接口返回Blob对象数据 6 xhr.onload = (response) => { 7 const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8' }) 8 const link = document.createElement('a'); 9 link.href = URL.createObjectURL(blob);//生成的 URL 映射 10 link.download = 'xxx.xlsx' 11 link.click(); 12 URL.revokeObjectURL(link.href);//释放内存 13 } 14 }