什么是 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);
}