Blob介绍
Blob( Binary Large Object ) 表示二进制类型的大对象。对于数据库管理系统来说,它将二进制数据存储为单一个体的集合,通常用于影像,声音或多媒体文件。
在JavaScript中,Blob类型表示不可变的类似文件对象的原始数据。
为了能够直观感受,创建一个Blob对象。
var text = '我是Blob对象'
var blob = new Blob([text],{type:'text/plain'})
Blob对象含有两个属性:size 和 type。
- size表示数据的大小(以字节为单位)
- type表示 MIME 的类型。
Blob 表示的也不一定是 JavaScript 原生格式的数据。比如 File 接口基于 Blob ,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
Blob构造函数的属性和方法
var blob = new Blob( array, options );
参数说明:
-
array 是一个由 Blob, DOMString , ArrayBuffer, ArrayBufferView,等对象构成的 Array。DOMStrings会被编码为UTF-8。
-
optinos一般默认会指定两个属性 .
- type: 默认值为 "",它代表了将会被放入到blob中的数组内容的MIME类型
- endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。主要有两个值: "native" 和 “transparent ”。 “native” 代表行结束符会被更改为适合宿主操作系统文件系统的换行符,"transparent"代表会保持blob中保存的结束符不变
例子1 :从DOMString创建Blob
var aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; // 一个包含DOMString的数组
var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // 得到 blob
例子2:从类型化数组和字符串创建 Blob
var hello = new Uint8Array([72, 101, 108, 108, 111]); // 二进制格式的 "hello"
var blob = new Blob([hello, ' ', 'semlinker'], {type: 'text/plain'});
方法说明
- arrayBuffer() 方法返回一个 Promise 对象,包含 blob 中的数据,并在 ArrayBuffer 中以二进制数据的形式呈现。
- slice() 方法用于创建一个包含源 Blob的指定字节范围内的数据的新 Blob 对象
- stream() 方法返回一个ReadableStream对象,读取它将返回包含在Blob中的数据。
- text() 方法返回一个 Promise 对象,包含 blob 中的内容,使用 UTF-8 格式编码
Blob的使用场景
1. 分片上传
onFile.addEventListener('change', async function (e) {
const file = e.target.files[0]
const chunkSize = 100
const url = '/tools_upload_image_v2/'
for (let start = 0; start < file.size; start += chunkSize) {
const chunk = file.slice(start, start + chunkSize + 1);
const fd = new FormData()
fd.append('Filedata', chunk)
await fetch(url, { body: fd, method: 'POST',headers:{}}).then(res => {
console.log('res', res)
}).catch(err=>{
console.log('err', err)
})
}
})
2. 下载文件
const imgUrl='https:/xxxxx/free_stock_photo.jpg'
onDownLoad.addEventListener('click', async () => {
await fetch(imagUrl).then(res => {
return res.blob()
}).then(blob=>{
let objectURL = URL.createObjectURL(blob);
onImgBg.src = objectURL;
})
})
Blob URL 是一种伪协议,允许Blob 和File对象作为图像,在浏览器中,使用 URL.createObjectURL() 方法来创建 Blob URL,该方法接收一个 Blob 对 象,并为其创建一个唯一的 URL,其形式为 blob:/
blob:http://xxxxx/5930e215-94ef-4ad2-8b58-a1057f0889b2
浏览器内部为每个通过 URL.createObjectURL 生成的 URL ,存储了一个 URL → Blob 映射。URL 的生命周期和创建它的窗口中的 document 绑定的,当窗口关闭的时候,这个链接也就失效了。
可以通过将跨域链接转换成 blob 伪协议,下载一个跨域的文件。
3. Blob 转换为 Base64
这个算是 URL.createObjectURL 的一个替代方法,将 Blob 转换为 base64 编码的字符串 。现代浏览器支持一种名为 Data URLs 的特性,允许使用 base64 对图片或其他文件的二进制数据进行编码,将其作为文本字符串嵌入网⻚中。
onBlobToBase64.addEventListener('click', () => {
if (saveBlob) {
var reader = new FileReader();
reader.onload = function (e) {
onImgBase.src = e.target.result
}
reader.readAsDataURL(saveBlob);
} else {
alert('请先获取Blob')
}
})
4. 图片压缩
let canvas = document.createElement("canvas");
let img = document.createElement("img");
img.crossOrigin = "anonymous";
const MAX_WIDTH = 800; // 图片最大宽度
return new Promise((resolve, reject) => {
img.src = base64;
img.onload = () => {
let targetWidth, targetHeight;
if (img.width > MAX_WIDTH) {
targetWidth = MAX_WIDTH;
targetHeight = (img.height * MAX_WIDTH) / img.width;
} else {
targetWidth = img.width;
targetHeight = img.height;
}
canvas.width = targetWidth;
canvas.height = targetHeight;
let ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, targetWidth, targetHeight); // 清除画布
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
let imageData = canvas.toDataURL(mimeType, quality / 100);
resolve(imageData);
};
});
图片越小,压缩之后反而变得更大;反之,图片越大,图片压缩之后,变大的比例就越小
canvas压缩图片的秘密_weixin_34114823的博客-CSDN博客
Blob 与 ArrayBuffer的区别
ArrayBuffer 对象代表储存二进制数据的一段内存,它不能直接读写,只能通过视图(TypedArray视图和DataView视图)来读写,视图的作用是以指定格式解读二进制数据。
Blob 类型的对象表示不可变的类似文件对象的原始数据。Blob 表示的不一定JavaScript 原生格式的数据。File 接口基于 Blob,继承了Blob 功能并将其扩展为支持用户系统上的文件。
两者的比较
- 除非你需要使用 ArrayBuffer 提供的写入/编辑的能力,否则 Blob 格式可能是最好的。
- Blob 对象是不可变的,而 ArrayBuffer 是可以通过 TypedArrays 或 DataView 来操作。
- ArrayBuffer 是存在内存中的,可以直接操作。而 Blob 可以位于磁盘、高速缓存内存和其他不可用的位置。
- ArrayBuffer 的数据,是可以按照字节去操作的,而 Blob 只能作为一个完整对象去处理。Blob 类型可以通过Sice 方法,返回一个新的Blob对象,包含了Blob对象中指定范围内的数据。
Blob 与 ArrayBuffer 对象之间是可以相互转化的:
- 使用 FileReader 的 readAsArrayBuffer() 方法,可以把 Blob 对象转换为 ArrayBuffer 对象;
- 使用 Blob 构造函数,如 new Blob([new Uint8Array(data]); ,可以把 ArrayBuffer 对 象转换为 Blob 对象。
function BlobToArryBuffer() {
const fileReader = new FileReader()
fileReader.readAsArrayBuffer(saveBlob)
console.log('转换前的Blob', saveBlob)
fileReader.onload = function () {
console.log('转换后的ArrayBuffer', fileReader.result)
arryBuffer = fileReader.result
}
}
function ArrayBufferToBlob() {
console.log('转换前的ArrayBuffer', arryBuffer)
const blob = new Blob([new Uint8Array(arryBuffer)], { type: "image/jpeg" })
console.log('转换后的Blob', blob)
}
使用总结
- 通过将跨域资源文件转换成 blob 伪协议,跳过跨域问题。使用场景,下载跨域文件资源
- 将blob转换成 base64,对于一些小文件可以减少请求,优化页面的加载