分类
HTML5对象:Blob、File、FileReader、ArrayBuffer、FormData
- Blob、ArrayBuffer、File归为一类,它们都是数据;
- FileReader 是一种用来读取数据的工具;
- FormData 是一个应用数据的场景;
Blob
概念
全称是binary large object,二进制大文件对象,非Javascript特有,计算机通用对象,MDN上解释是,一个Blob对象就是一个包含有只读原始数据的类文件对象,通俗讲就是不可修改的二进制文件。
通过构造函数创建Blob对象
/**
* Blob构造函数:
* dataArray:数组,包含了要添加到Blob对象中的数据,数据可以是Int32Array、Uint8Array、Float32Array等,或者连续内存缓冲区ArrayBuffer,ArrayBufferView, Blob,或者 DOMString对象。
* opt:对象,用于设置Blob对象的属性(如:MIME类型)
**/
var blob = new Blob(dataArr:Array<any>, opt:{
type:string});
// 创建一个装填DOMString对象的Blob对象
var dom = '<div>hello</div>'
var blobObj = new Blob([dom], {
type: 'text/xml'})
// 创建一个装填ArrayBuffer对象的Blob对象
var kite = new ArrayBuffer(8)
var blobOjb = new Blob([kite], {
type: 'text/plain'})
属性
- size:数据的字节大小(只读)
- type:数据的MIME类型,例如’image/jpeg’(只读) (MIME:描述消息内容类型的因特网标准)
方法
Blob.slice() 此方法返回一个新的Blob对象,包含了原Blob对象中指定范围内的数据,利用此方法可以实现大文件的分片上传
- Blob.slice()
Blob.slice(start, end ,contentType)
//start:分割起始点
//end: 分割终点
//contentType:新的MIME类型
- Blob.stream() 返回一个能读取 blob 内容的 ReadableStream。
- Bob.text() 返回一个 promise 且包含 blob 所有内容的 UTF-8 格式的 USVString。
- Blob.arrayBuffer() 返回一个 promise 且包含 blob 所有内容的二进制格式的 ArrayBuffer。
ArrayBuffer
概念
ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区,是内存上一段二进制数据,我们可以借助工具类型数组对象、DataView对它进行读写。
Blob与ArrayBuffer的关系
- 相同点: Blob和ArrayBuffer都是二进制的容器;
- ArrayBuffer是底层二进制数据,可以对其任何一个字节进行单独的修改,也可以根据我们的需要以我们指定的形式读取指定范围的数据,而Blob是对底层二进制数据的封装,我们拿到的就是一个整体,能够读取他的大小,类型,可以对其分割,但是不能看到细节;
- Blob可以接受一个ArrayBuffer作为参数生成一个Blob对象,此行为就相当于 ArrayBuffer数据做一个封装,之后就是以整体的形式展现了
- 应用:Blob作为一个整体文件,适合用于传输;而只有需要关注细节(比如要修改某一段数据时),才需要用到ArrayBuffer
示例
// 下面的例子创建了一个 8 字节的缓冲区,并使用一个 Int32Array 来引用它:
var buffer = new ArrayBuffer(8);
var view = new Int32Array(buffer);
File
概念解释
File就是文件,继承自Blob,也是二进制对象,File是Blob的子类,比blob主要多出一个name的属性。 也有自己特有的属性和方法,通常用在选择的FileList对象,或者是使用拖拽操作产生的的DataTransfer对象。
构造函数创建File对象
const file = new File(array, name,options);
// array:一堆数据构成的数组
//name:文件名
//options:设置一些属性,type属性、lastModified
属性
- name:文件名
- size:文件大小
- lastModified :最后修改时间(时间戳)
- lastModifiedDate:最后修改时间Data对象
- type:MIME类型
File对象方法
- 继承了Blob的slice方法
FileReader
概念
Blob对象只是二进制数据的容器,本身并不能操作二进制,FileReader对象就是专门操作二进制数据的,FileReader主要用于将文件内容读入内存,通过一系列异步接口,可以在主线程中访问本地文件。
通过fileReader可以将Blob、File读取为不同的格式
创建实例
const reader = new FileReader();
方法 (参数:File或Blob对象)
- reader.readAsArrayBuffer(file) 异步按字节读取文件内容,结果用ArrayBuffer对象表示
- reader.readAsBinaryString(file) 异步按字节读取文件内容,结果为文件的二进制串
- reader.readAsDataURL(file) 异步读取文件内容,结果用data:url(即Base64格式)的字符串形式表示
- reader.readAsText(file, encoding) 异步按字符读取文件内容,结果用字符串形式表示
- reader.abort() 终止文件读取操作
属性
- reader.error 一个DOMException,表示在读取文件时发生的错误
- reader.readyState 表示FileReader状态的数字(0: 还没有加载数据、1:正在加载、 2:已完成全部的读取请求)
- reader.result 文件的内容。该属性仅在读取操作完成后才有效,数据的格式取决于使用哪个方法来启动读取操作。
事件名称
- onabort 当读取操作被中止时调用
- onerror 当读取操作发生错误时调用
- onload 当读取操作成功完成时调用
- onloadend 当读取操作完成时调用,不管是成功还是失败
- onloadstart 当读取操作将要开始之前调用
- onprogress 在读取数据过程中周期性调用
FormData
概念
FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 “multipart/form-data”,它会使用和表单一样的格式。
FormData的最大优点就是,比起普通的ajax, 使用FormData我们可以异步上传一个二进制文件,而这个二进制文件,就是我们上面讲的Blob对象。
构造函数
const formData = new FormData()
方法
- formData.append() 向 FormData 中添加新的属性值,FormData 对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值。
- formData.delete() 从 FormData 对象里面删除一个键值对。
- formData.entries() 返回一个包含所有键值对的iterator对象。
- formData.get() 返回在 FormData 对象中与给定键关联的第一个值。
应用实际业务场景
- File文件转换为Blob对象
let blob = new Blob([file], {
type: file.type})
- Blob转换为File
let files = new window.File([this.blob], file.name, {
type: file.type})
- File/Blob文件转换为base64
function blobToDataURL(blob, callback) {
let fileReader = new FileReader();
fileReader.onload = function (e) {
callback(e.target.result); }
fileReader.readAsDataURL(blob);
}
- 图片url转换为base64
image2base64(imgUrl) {
let image = new Image()
image.src = imgUrl
return new Promise((resolve) => {
image.onload = () => {
let canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
var context = canvas.getContext('2d')
context.drawImage(image, 0, 0, image.width, image.height)
let dataUrl = canvas.toDataURL('image/png')
resolve(dataUrl)
}
})
}
- base64转Blob
function dataURLtoBlob(dataurl) {
const arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime });
}
- base64转File
function dataURLtoFile(dataurl, filename) {
const arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {
type:mime });
}
- 读取表格类的文件行数(xlsx)
readFileRows(file) {
return new Promise((resolve, reject) => {
try {
const fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
let data = [];
fileReader.onload = ({
target:{
result} = {
}}) => {
const wb = XLSX.read(result, {
type: 'buffer' });
const firstSheet = wb.Sheets[wb.SheetNames[0]];
data = XLSX.utils.sheet_to_json(firstSheet);
resolve({
rows: data.length });
};
} catch (error) {
reject(new Error('read failed'));
this.$message.error('文件行数读取失败!');
}
});
},