Blob介绍
blob表示二进制大对象(binary larget object),是一个不可变、原始数据的类文件对象。同时Blob还是File的超类。
可能这么说有点模糊,我们可以把blob理解为使用二进制保存数据的对象,这个对象保存的数据可以是很多内容,例如字符串、ArrayBuffer、ArrayBufferView、Domstring,甚至是其他的blob都可以,它们以二进制的形式保存在blob中,但是不同于ArrayBuffer,ArrayBuffer中的二进制数据可以通过TypeArray或者DataView写入修改,Blob中的二进制数据是不可修改的。
Blob API
构造函数
语法:
var aBlob = new Blob( array, options );
Blob()构造函数接收两个参数:
- array:是一个由字符串、ArrayBuffer、ArrayBufferView、Domstring等对象组成的Array。
- options :是一个可选的
BlobPropertyBag字典,它可能会指定如下两个属性:- type:指定被放入到 blob 中的数组内容的 MIME 类型,默认值是
"" - endings:默认值为
"transparent"。用于指定包含行结束符\n的字符串如何被写入。有两个值,一个是"native",代表行结束符会被更改为适合宿主操作系统文件系统的换行符,另一个是"transparent",代表会保持 blob 中保存的结束符不变
- type:指定被放入到 blob 中的数组内容的 MIME 类型,默认值是
//Domstring
const domString = new Blob(['<a id="a"></a>'], {type : 'text/html'});
//普通文本
const text=new Blob(['这是一段文字'],{type:"text/plain"})
//ArrayBuffer
const bufferBlob=new Blob([new ArrayBuffer(12)])
实例属性
通过Blob()构造函数创建的实例拥有两个属性:
- size:字节大小
- type:实例的MIME类型
实例方法
Blob实例上有四个方法
-
text():返回一个promise对象,以 resolve 状态返回一个以文本形式包含 blob 中数据的 String对象
const blob=new Blob(['这是一段文字'],{type:"text/plain"}) const textPromise=blob.text() textPromise.then(text=>{ console.log(text)//这是一段文字 console.log(typeof(text))//string }) -
stream():返回一个ReadableStream对象。具体ReadableStream对象的使用可查看MDN文档
const blob=new Blob(['这是一段文字'],{type:"text/plain"}) const stream=blob.stream() console.log(stream)//ReadableStream对象 -
arrayBuffer():返回一个 resolve 状态的promise对象,
resolveValue是一个ArrayBuffer对象。const blob=new Blob(['这是一段文字'],{type:"text/plain"}) const bufferPromise=blob.arrayBuffer() bufferPromise.then(buffer=>console.log(buffer))//ArrayBuffer -
slice([start [, end [, contentType]]]):以指定字节范围复制blob的数据,并返回一个blob实例。start是开始字节位置,end是结束字节位置(包括),contentType可以给返回的blob实例指定type
const blob=new Blob(['这是一段文字'],{type:"text/plain"}) const other=blob.slice(0,3,"text/plain") other.text().then(res=>console.log(res))//这
应用场景
图片预览
我们通常会遇到这样一个场景:用户预览本地选择的图片。通常我们有两种方法实现:
- 通过FileReader的
readAsDataURL来实现 - 利用
URL.createObjectURL()。这个函数可以传入File对象或者Blob对象,返回一个指向内存中地址的URL字符串。
const input = document.createElement("input")
input.type="file"
input.onchange=(e)=>{
const file=input.files[0]
const url=URL.createObjectURL(file)
//将url放到image标签上即可显示图片
URL.revokeObjectURL(file)
}
document.body.append(input)
下载文件
利用a标签下载文件
const button=document.createElement('button')
button.textContent="下载"
button.onclick=()=>{
const blob=new Blob(['这是一段文本内容'],{type:"text/plain"})
const a=document.createElement('a')
a.href=URL.createObjectURL(blob)
a.download="blob.txt"
a.click()
a.remove()
URL.revokeObjectURL(blob)
}
document.body.append(button)
分片上传
针对大文件的上传,我们可以利用blob的slice方法将数据切割上传。
const file = new Blob(["a".repeat(100000)], {type:"text/plain"});
const size = 10000;
const url = "https://httpbin.org/post";
async function chunkedUpload() {
for (let start = 0; start < file.size; start += size) {
const chunk = file.slice(start+1, start + size);
const fd = new FormData();
fd.append("data", chunk);
await fetch(url, { method: "post", body: fd }).then((res) =>
res.text()
);
}
}
对象转换
Blob和ArrayBuffer转换
Blob--->ArrayBuffer:
const blob=new Blob(['这是一段文字'],{type:"text/plain"})
//利用FileReader
const read=new FileReader()
read.readAsArrayBuffer(blob)
read.onload=()=>{
console.log(read.result)//ArrayBuffer
}
//利用Blob.arrayBuffer()
const bufferPromise=blob.arrayBuffer()
bufferPromise.then(buffer=>{
console.log(buffer)//ArrayBuffer
})
ArrayBuffer--->Blob:
//通过Blob()构造函数
const buffer=new ArrayBuffer(8)
const blob=new Blob([buffer])