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 对象,具体如下图所示:
0
如你所见,myBlob 对象含有两个属性:size 和 type。其中 size 属性用于表示数据的大小(以字节为单位),type 是 MIME 类型的字符串。Blob 表示的不一定是JavaScript 原生格式的数据。比如 File 接口基于 Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件
 
Blob 由一个可选的字符串 type(通常是 MIME 类型)和 blobParts 组成:
0
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 }
posted @ 2022-10-10 13:55  web-慰尘  阅读(3195)  评论(0编辑  收藏  举报