什么是blob?
以下是MDN的官方解释:
Blob
对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成ReadableStream
来用于数据操作。
Blob 表示的不一定是JavaScript原生格式的数据。File
接口基于Blob
,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
要从其他非blob对象和数据构造一个Blob
,请使用Blob()
构造函数。
实际上 file
对象只是 blob
对象的一个更具体的版本,blob
存储着大量的二进制数据,并且 blob
的 size
和 type
属性,都会被 file
对象所继承。
所以, 在大多数情况下,blob
对象和 file
对象可以用在同一个地方,例如,可以使用 FileReader
借口从 blob
读取数据,也可以使用 URL.createObjectURL()
从 blob
创建一个新的 URL
对象。
blob的创建
Blob() 构造函数
允许通过其它对象创建 Blob 对象。比如,用字符串构建一个 blob
var debug = {hello: "world"};
var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});
构造函数,接受两个参数,第一个为一个数据序列,可以是任意格式的值,例如,任意数量的字符串,Blobs 以及 ArrayBuffers。第二个参数,是一个包含了两个属性的对象,其两个属性分别是:
type -- MIME 的类型。
endings -- 决定 append() 的数据格式,(数据中的 \n 如何被转换)可以取值为 "transparent" 或者 "native"(t 的话不变,n 的话按操作系统转换;t* 为默认) 。
blob的应用
大文件分割(分片上传)
slice() 方法接受三个参数,起始偏移量,结束偏移量,还有可选的 mime 类型。如果 mime 类型,没有设置,那么新的 Blob 对象的 mime 类型和父级一样。
当要上传大文件的时候,此方法非常有用,可以将大文件分割分段,然后各自上传,因为分割之后的 Blob 对象和原始的是独立存在的。
不过目前浏览器实现此方法还没有统一,火狐使用的是 mozSlice() ,Chrome 使用的是 webkitSlice() ,其他浏览器则正常的方式 slice()
可以写一个兼容各浏览器的方法:
function sliceBlob(blob, start, end, type) {
type = type || blob.type;
if (blob.mozSlice) {
return blob.mozSlice(start, end, type);
} else if (blob.webkitSlice) {
return blob.webkitSlice(start, end type);
} else {
throw new Error("This doesn't work!");
}
}
文件流下载
后端返回的数据是文件流的时候,需要在axios请求指定responseType:
// 下载接口 文件下载
export function downloadRes(data) {
return request({
timeout: 30000,
responseType: 'blob', // 需要指定
baseURL: 'xxx',
method: 'post',
data
})
}
这是返回的data就是blob类型数据,但是我们下载的话还需要一个文件名,后端会默认指定把文件名放在content-disposition
这个响应头:
let fileName = '';
const contentDisposition = res.headers['content-disposition'];
if (contentDisposition) {
fileName = window.decodeURI(res.headers['content-disposition'].split('=')[1], "UTF-8");
}
创建blob对象,创建reader,监听加载时间,创建a标签,模拟点击事件,移除a标签。这就是一个文件流下载的基本流程:
const blob = new Blob([res.data]);
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = (e) => {
const a = document.createElement('a');
a.download = fileName;
a.href = e.target.result;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。