blob
Blob
由一个可选的字符串 type
(通常是 MIME 类型)和 blobParts
组成 —— 一系列其他 Blob
对象,字符串和 BufferSource,blob就是
具有类型的二进制数据
MIME 类型
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
更多关于MIME 类型 可以参考 MIME 类型
常见的 MIME 类型
-
超文本标记语言文本 .html、.html:text/html
-
普通文本 .txt: text/plain
-
RTF 文本 .rtf: application/rtf
-
GIF 图形 .gif: image/gif
-
JPEG 图形 .jpeg、.jpg: image/jpeg
-
au 声音文件 .au: audio/basic
-
MIDI 音乐文件 mid、.midi: audio/midi、audio/x-midi
-
RealAudio 音乐文件 .ra、.ram: audio/x-pn-realaudio
-
MPEG 文件 .mpg、.mpeg: video/mpeg
-
AVI 文件 .avi: video/x-msvideo
-
GZIP 文件 .gz: application/x-gzip
-
TAR 文件 .tar: application/x-tar
构造blob对象
Blob
构造器允许从几乎任何东西创建 blob
let blob = new Blob([],{});
参数1:数组, 内部存放Blob
/BufferSource
/String
类型的值。
参数2:对象(可选),
type
—— 指定Blob
对象的类型,通常是 MIME 类型,例如image/png
,endings
—— 是否转换换行符,使Blob
对应于当前操作系统的换行符(\r\n
或\n
)。默认为"transparent"
(啥也不做),不过也可以是"native"
(转换)。
构造一个文本类的blob对象
let hello = new Uint8Array([72, 101, 108, 108, 111]); // 二进制格式的 "hello"
let blob = new Blob([hello,"world"],{type:"text/plain"});
console.log(blob);
这里表示长度为10的txt文本
slice
方法来提取 Blob
片段:
blob.slice([byteStart], [byteEnd], [contentType]);
byteStart
—— 起始字节,默认为 0。byteEnd
—— 最后一个字节(不包括,默认为最后)。contentType
—— 新 blob 的type
,默认与源 blob 相同。
参数值类似于 array.slice
,也允许是负数。
let sliceBlob = blob.slice(0,5,"text/plain");
console.log(sliceBlob);
Blob
对象是不可改变的
我们无法直接在 Blob
中更改数据,但我们可以通过 slice
获得 Blob
的多个部分,从这些部分创建新的 Blob
对象,将它们组成新的 Blob
,等。例如,blob可能表示一张图片,我们并不能改变这张原图片,这就像字符串的一些方法并不改变原字符串那样。
blob用作url
blob是二进制数据,直接打印并不直观,我们可以通过<a>
、<img>
或其他标签的 URL,来显示它们的内容。
<a download="hello.txt" href='#' id="link">Download</a>
document.getElementById("link").href = URL.createObjectURL(blob);
利用a标签的download属性和URL的方法将blob对象转成url并下载
可以看到blob里面存放的是一个txt类型的文本数据,内容是helloworld
URL.createObjectURL
取一个 Blob
,并为其创建一个唯一的 URL,形式为 blob:<origin>/<uuid>
blob:源网页地址,特定的id码
我们可以看到a标签的href属性就是一个blob url
blob url只允许在源网页使用,而且具有临时性,仅在当前文档打开的状态下才有效。
浏览器内部为每个通过 URL.createObjectURL
生成的 URL 存储了一个 URL → Blob
映射。虽然这里有 Blob
的映射,但Blob
本身只保存在内存中的。浏览器无法释放它。如果我们创建一个 URL,那么即使我们不再需要该 Blob
了,它也会被挂在内存中。URL.revokeObjectURL(url)
从内部映射中移除引用,因此允许 Blob
被删除(如果没有其他引用的话),并释放内存。
blob转base64 (data-url)
Blob
转换为 base64-编码的字符串。这种编码将二进制数据表示为一个由 0 到 64 的 ASCII 码组成的字符串,非常安全且“可读“。更重要的是 —— 我们可以在 “data-url” 中使用此编码。
“data-url” 的形式为 data:[<mediatype>][;base64],<data>
。我们可以在任何地方使用这种 url,和使用“常规” url 一样。
<img src="data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7">
let reader = new FileReader();
reader.readAsDataURL(blob); // 将 Blob 转换为 base64 并调用 onload
reader.onload = function() {
link.href = reader.result; // data url
};
这部分的作用和blob url 的效果一样
image图片转blob
我们可以创建一个图像(image)的、图像的一部分、或者甚至创建一个页面截图的 Blob
。这样方便将其上传至其他地方。
图像操作是通过 <canvas>
元素来实现的:
- 使用 canvas.drawImage 在 canvas 上绘制图像(或图像的一部分)。
- 调用 canvas 方法 .toBlob(callback, format, quality) 创建一个
Blob
,并在创建完成后使用其运行callback
。
// 获取任何图像
let img = document.querySelector('img');
// 生成同尺寸的 <canvas>
let canvas = document.createElement('canvas');
canvas.width = img.clientWidth;
canvas.height = img.clientHeight;
let context = canvas.getContext('2d');
// 向其中复制图像(此方法允许剪裁图像)
context.drawImage(img, 0, 0);
// 我们 context.rotate(),并在 canvas 上做很多其他事情
// toBlob 是异步操作,结束后会调用 callback
canvas.toBlob(function (blob) {
// blob 创建完成,下载它
let link = document.createElement('a');
link.download = 'example.png';
link.href = URL.createObjectURL(blob);
link.click();
// 删除内部 blob 引用,这样浏览器可以从内存中将其清除
URL.revokeObjectURL(link.href);
}, 'image/png');
这样当页面加载后会直接下载img图片
blob和 ArrayBuffer ,stream
我们可以从 blob.arrayBuffer()
中获取最低级别的 ArrayBuffer
关于ArrayBuffer--- js二进制数据,文件---ArrayBuffer,二进制数组-优快云博客
blob.arrayBuffer().then(buffer =>{
/* 处理 ArrayBuffer */
console.log(buffer);
});
Blob
接口里的 stream()
方法返回一个 ReadableStream
,在被读取时可以返回 Blob
中包含的数据。
// 从 blob 获取可读流(readableStream)
const readableStream = blob.stream();
const stream = readableStream.getReader();
(async()=>{
while (true) {
// 对于每次迭代:value 是下一个 blob 数据片段
let { done, value } = await stream.read();
if (done) {
// 读取完毕,stream 里已经没有数据了
console.log('all blob processed.');
break;
}
// 对刚从 blob 中读取的数据片段做一些处理
console.log(value);
}
})()
总结
blob是具有类型的二进制数据
Blob
在浏览器中常用于上传/下载操作
XMLHttpRequest,fetch 等进行 Web 请求的方法可以自然地使用 Blob,二进制数据传递效率最高
- 我们可以使用
new Blob(...)
构造函数从一个类型化数组(typed array)创建Blob
。 - 我们可以使用
blob.arrayBuffer()
从Blob
中取回arrayBuffer
,然后在其上创建一个视图(view),用于低级别的二进制处理。
完整代码展示
为了不影响结果展示,部分代码被注释
// blob.js
let hello = new Uint8Array([72, 101, 108, 108, 111]); // 二进制格式的 "hello"
let blob = new Blob([hello, "world"], { type: "text/plain" });
console.log(blob);
let sliceBlob = blob.slice(0, 5, "text/plain");
console.log(sliceBlob);
document.getElementById("link").href = URL.createObjectURL(blob);
// let reader = new FileReader();
// reader.readAsDataURL(blob); // 将 Blob 转换为 base64 并调用 onload
// reader.onload = function() {
// link.href = reader.result; // data url
// };
// 获取任何图像
let img = document.querySelector('img');
// 生成同尺寸的 <canvas>
let canvas = document.createElement('canvas');
canvas.width = img.clientWidth;
canvas.height = img.clientHeight;
let context = canvas.getContext('2d');
// 向其中复制图像(此方法允许剪裁图像)
context.drawImage(img, 0, 0);
// 我们 context.rotate(),并在 canvas 上做很多其他事情
// toBlob 是异步操作,结束后会调用 callback
canvas.toBlob(function (blob) {
// blob 创建完成,下载它
let link = document.createElement('a');
link.download = 'example.png';
link.href = URL.createObjectURL(blob);
// link.click();// 触发a标签点击事件
// 删除内部 blob 引用,这样浏览器可以从内存中将其清除
URL.revokeObjectURL(link.href);
}, 'image/png');
blob.arrayBuffer().then(buffer => {
/* 处理 ArrayBuffer */
// console.log(buffer);
});
// 从 blob 获取可读流(readableStream)
const readableStream = blob.stream();
const stream = readableStream.getReader();
(async()=>{
while (true) {
// 对于每次迭代:value 是下一个 blob 数据片段
let { done, value } = await stream.read();
if (done) {
// 读取完毕,stream 里已经没有数据了
console.log('all blob processed.');
break;
}
// 对刚从 blob 中读取的数据片段做一些处理
console.log(value);
}
})()
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>blob</title>
</head>
<body>
<img src="data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7">
<a download="hello.txt" href='#' id="link">Download</a>
<script src="blob.js"></script>
</body>
</html>