「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」
上周,写了2篇关于资源下载保存的文章,一篇是在资源不超过浏览器Blob大小限制并且浏览器RAM够的情况下,另一篇是如何突破浏览器内存限制保存下载超大资源文件(超过2G)。感兴趣的话,可以看看。本系列是对上面2篇文章的一个扩展,通过Blob/File扩展出所有可能存在的类型,属于个人学习笔记。
传送门:
再看资源文件下载保存,如何健壮?
前端自个突破浏览器Blob和RAM大小限制保存文件的骚玩法!
概览
下面是一张关于二进制数据相关数据类型的可转换的图片,下面我们按流程指向学习,
本篇文章写:读取Blob为ArrayBuffer或者Data URL。
-
Blob
Blob对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 [ReadableStream] 来用于数据操作。 -
ArrayBuffer
ArrayBuffer对象用来表示通用的、固定长度的原始二进制数据缓冲区。它是一个字节数组,通常在其他语言中称为“byte array”。你不能直接操作ArrayBuffer的内容,而是要通过[类型数组对象]或 [DataView] 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。 -
DataURLs Data URLs,即前缀为
data:协议的URL,其允许内容创建者向文档中嵌入小文件。Data URLs 由四个部分组成:前缀(data:)、指示数据类型的MIME类型、如果非文本则为可选的base64标记、数据本身:
data:[<mediatype>][;base64],<data>
了解完基本类型概念,下面就看看如何读取Blob,当然了,Js中并没有直接读取Blob数据的方法,所以需要一些转换。 ,否则本文就没有意义了。
实现
1. Blob.arrayBuffer
通过Blob.arrayBuffer()它会返回一个promise对象,包含blob所有内容的二进制格式arraybuffer。
var debug = {hello: "world"};
var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});
// 异步获取
blob.arrayBuffer().then(arraybuffer=>console.log(arraybuffer))
2. 借助FileReader
FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 [File] 或 [Blob] 对象指定要读取的文件或数据。它暴露了几个api,可以以如下方式读取Blob中的内容。
- readAsArrayBuffer:读取后,result属性保存的是arraybuffer数据对象
- readAsBinaryString:读取后,result属性保存原始二进制数据
- readAsDataURL:读取后,result属性包含一个data:URL 格式的base64字符串
- readAsText():读取后,result属性包含一个字符串
var reader = new FileReader();
// 读取结束触发
reader.addEventListener("loadend", function() {
// reader.result 包含被转化为类型数组 typed array 的 blob
});
reader.readAsArrayBuffer(blob);
3. Response构造函数
Fetch API的 Response 接口呈现了对一次请求的响应数据。你可以使用Response.Response() 构造函数来创建一个 Response 对象。
let myResponse = new Response(body, init);
body参数可选,也可以为null,或者是下面一个:
- Blob
- BufferSource
- FormData
- ReadableStream
- URLSearchParams
- USVString
所以可以通过该构造函数读取Blob,当然类型得对得上:
var text = await (new Response(blob)).text();
var arrayBuffer = await (new Response(blob)).arrayBuffer();
var json = await (new Response(blob)).json();
4. 扩展ReadableStream
流操作API中的ReadableStream接口呈现了一个可读取的二进制流操作。Fetch API通过Response的属性body提供了一个具体的ReadableStream对象。
fetch("https://www.example.org/").then((response) => {
// 创建一个读取器并将流锁定于其上,一旦被锁定,其他读取器不能读取它,直至它被释放。
const reader = response.body.getReader();
const stream = new ReadableStream({
start(controller) {
// 下面的函数处理每个数据块
function push() {
// "done"是一个布尔型,"value"是一个Uint8Array
reader.read().then(({ done, value }) => {
// 判断是否还有可读的数据?
if (done) {
// 告诉浏览器已经结束数据发送
controller.close();
return;
}
// 取得数据并将它通过controller发送给浏览器
controller.enqueue(value);
push();
});
};
push();
}
});
return new Response(stream, { headers: { "Content-Type": "text/html" } });
});
总结
这便是读取Blob的几种方式,下一篇就计划看看ArrayBuffer和TypeArray。最后关于读取流相关,建议看看传送门:前端自个突破浏览器Blob和RAM大小限制保存文件的骚玩法!,这里有实战。
再最后,客户留个赞呗!带你五点重温JS宝典~