JS的Blob、ArrayBuffer、File、FileReader、Object URL、base64和FormData

一图即可理解关系

Blob

定义

一个包含有只读原始数据的类文件对象。通俗讲就是不可修改的二进制文件

创建一个blob对象

let aBlob = new Blob( array, options );

Blob对象的属性
  • size:数据的字节大小(只读)
  • type:数据的MIME类型,例如'image/jpeg'(只读) (MIME:描述消息内容类型的因特网标准)
Blob对象的方法

Blob.slice(start, end ,contentType)        contentType(可选):表示提取出来的数据的MIME类型。如果不指定,则新Blob对象的MIME类型将与原Blob对象相同。

const blob = new Blob(["<p>HELLO</p>"], {type: "text/html"});

const subBlob = blob.slice(0, 6, "text/html"); //Blob {size: 6, type: 'text/html'}

File

概念

File就是文件,继承自Blob,也是二进制对象,也有自己特有的属性和方法,通常用在<input type="file">选择的FileList对象,或者是使用拖拽操作产生的的DataTransfer对象。

创建一个blob对象

var myFile = new File(array, name,options);

File对象属性
  • name:文件名
  • size:文件大小
  • lastModified :最后修改时间(时间戳)
  • lastModifiedDate:最后修改时间Data对象
  • type:MIME类型 
File对象方法 

继承自Blobslice方法

ArrayBuffer

概念

ArrayBuffer是内存上一段二进制数据,我们可以借助工具TypedArray、DataView对它进行读写

和Blob关系

ArrayBuffer是底层二进制数据,可以借助工具进行读写,而Blob是对底层二进制数据的封装,我们拿到的就是一个整体,能够读取他的大小,类型,但是不能看到细节
Blob可以接受一个ArrayBuffer作为参数生成一个Blob对象,此行为就相当于对ArrayBuffer数据做一个封装,之后就是以整体的形式展现了
Blob作为一个整体文件,适合用于传输;而只有需要关注细节(比如要修改某一段数据时),才需要用到ArrayBuffer

用法
创建,属性,方法
const buffer = new ArrayBuffer(16); 
console.log(buffer.byteLength)  // 16
console.log(buffer.slice(0, 8))    //ArrayBuffer(8)
ArrayBuffer.isView()

用来判断参数是否是 TypedArray 实例或者 DataView 实例:

const buffer = new ArrayBuffer(16);
ArrayBuffer.isView(buffer)   // false

const view = new Uint32Array(buffer);
ArrayBuffer.isView(view)     // true
TypedArray 

TypedArray 对象一共提供 9 种类型的视图,每一种视图都是一种构造函数。如下:

元素类型化数组字节描述
Int8Int8Array18 位有符号整数
Uint8Uint8Array18 位无符号整数
Uint8CUint8ClampedArray18 位无符号整数
Int16Int16Array216 位有符号整数
Uint16Uint16Array216 位无符号整数
Int32Int32Array432 位有符号整数
Uint32Uint32Array432 位无符号整数
Float32Float32Array432 位浮点
Float64Float64Array864 位浮点

这些类型化数组的特点:元素都是连续的,不会为空;所有成员的类型和格式相同,默认值为 0;本质上只是一个视图层,不会存储数据,数据都存储在更底层的 ArrayBuffer 对象中。

创建

new Int8Array(length);
new Int8Array(typedArray);
new Int8Array(object);
new Int8Array(buffer [, byteOffset [, length]]);

let view = new Int8Array(16);
view[0] = 10;
view[10] = 6;
console.log(view); //Int8Array(16) [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, buffer: ArrayBuffer(16), byteLength: 16, byteOffset: 0, length: 16, Symbol(Symbol.toStringTag): 'Int8Array']

let view = new Int8Array(new Uint8Array(6));
view[0] = 10;
view[3] = 6;
console.log(view); //Int8Array(6) [10, 0, 0, 6, 0, 0, buffer: ArrayBuffer(6), byteLength: 6, byteOffset: 0, length: 6, Symbol(Symbol.toStringTag): 'Int8Array']

let view = new Int8Array([1, 2, 3, 4, 5]);
view[0] = 10;
view[3] = 6;
console.log(view); //Int8Array(5) [10, 2, 3, 6, 5, buffer: ArrayBuffer(5), byteLength: 5, byteOffset: 0, length: 5, Symbol(Symbol.toStringTag): 'Int8Array']

let view = new Int16Array(new ArrayBuffer(8))
console.log(view) //Int16Array(4) [0, 0, 0, 0, buffer: ArrayBuffer(8), byteLength: 8, byteOffset: 0, length: 4, Symbol(Symbol.toStringTag): 'Int16Array']
let view2 = new Int8Array(new ArrayBuffer(8),1)
console.log(view2) //Int8Array(7) [0, 0, 0, 0, 0, 0, 0, buffer: ArrayBuffer(8), byteLength: 7, byteOffset: 1, length: 7, Symbol(Symbol.toStringTag): 'Int8Array']
 属性
  • buffer:返回内存中对应的 ArrayBuffer对象,只读属性

  • byteLength:返回 TypedArray 占据的内存长度,单位为字节;

  • length:返回 TypedArray 元素个数;

const view = new Int32Array(8)
console.log(view.buffer); // ArrayBuffer(32)
console.log(view.byteLength); //32
console.log(view.length); //8
DataView 

DataView 视图是一个可以从 二进制 ArrayBuffer 对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的字节序问题。

创建

new DataView(buffer [, byteOffset [, byteLength]])

属性
  • buffer:返回对应的ArrayBuffer对象;
  • byteLength:返回占据的内存字节长度;
  • byteOffset:返回当前视图从对应的ArrayBuffer对象的哪个字节开始。
const view = new DataView(new ArrayBuffer(16));
console.log(view); //DataView(16)
console.log(view.byteLength); //16
console.log(view.byteOffset); //0
写入和读取内存

写入(位置,整数数据)

  • setInt8:写入1个字节的8位整数。
  • setUint8:写入1个字节的8位无符号整数。
  • setInt16:写入2个字节的16位整数。
  • setUint16:写入2个字节的16位无符号整数。
  • setInt32:写入4个字节的32位整数。
  • setUint32:写入4个字节的32位无符号整数。
  • setFloat32:写入4个字节的32位浮点数。
  • setFloat64:写入8个字节的64位浮点数。

读取(位置)

  • getInt8:读取1个字节,返回一个8位整数。
  • getUint8:读取1个字节,返回一个无符号的8位整数。
  • getInt16:读取2个字节,返回一个16位整数。
  • getUint16:读取2个字节,返回一个无符号的16位整数。
  • getInt32:读取4个字节,返回一个32位整数。
  • getUint32:读取4个字节,返回一个无符号的32位整数。
  • getFloat32:读取4个字节,返回一个32位浮点数。
  • getFloat64:读取8个字节,返回一个64位浮点数。
let view = new DataView(new ArrayBuffer(16))
view.setInt16(0,100);
view.getInt8(0); //0
view.getInt8(1); //100

FileReader

FileReader 可以将 Blob 读取为不同的格式。

基本使用
创建

const reader = new FileReader();

属性
  • error:表示在读取文件时发生的错误;
  • result:文件内容。该属性仅在读取操作完成后才有效,数据的格式取决于使用哪个方法来启动读取操作。
  • readyState:表示FileReader状态的数字。0没有加载;1加载中;2已完成。
方法
  • readAsArrayBuffer(Blob ):读取指定 Blob 中的内容,完成之后,result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象;
  • FileReader.readAsBinaryString(Blob ):读取指定 Blob 中的内容,完成之后,result 属性中将包含所读取文件的原始二进制数据;
  • FileReader.readAsDataURL(Blob ):读取指定 Blob 中的内容,完成之后,result 属性中将包含一个data: URL 格式的 Base64 字符串以表示所读取文件的内容。
  • FileReader.readAsText(Blob ):读取指定 Blob 中的内容,完成之后,result 属性中将包含一个字符串以表示所读取的文件内容。
事件处理
  • abort:该事件在读取操作被中断时触发;
  • error:该事件在读取操作发生错误时触发;
  • load:该事件在读取操作完成时触发;
  • progress:该事件在读取 Blob 时触发。

可通过前置 on或者addEventListener形式来监听。

例子

将上传的图片显示在页面上 

<input type="file" id="fileInput" />

<img id="preview" />

const fileInput = document.getElementById("fileInput");
const preview = document.getElementById("preview");
const reader = new FileReader();

fileInput.onchange = (e) => {
  reader.readAsDataURL(e.target.files[0]);
};

reader.onload = (e) => {
  preview.src = e.target.result;
  console.log(e.target.result);
};

Object URL

Object URL又称Blob URL,是HTML5中的新标准。平时看到的blob:https://www.youtube.com/fd40f316-424 就是Object URL;我们可以在<img><script> 标签中或者 <a> 和 <link> 标签的 href 属性中使用这个 URL。

方法

createObjectURL(File/Blob);

revokeObjectURL(objectURL);

例子

同样的将上传的图片显示在页面上,可以改写成

const fileInput = document.getElementById("fileInput");
const preview = document.getElementById("preview");

fileInput.onchange = (e) => {
  preview.src = URL.createObjectURL(e.target.files[0]);
  console.log(preview.src);
};

Base64 

Base64 是一种基于64个可打印字符来表示二进制数据的表示方法。

方法
  • atob():解码,解码一个 Base64 字符串;
  • btoa():编码,从一个字符串或者二进制数据编码一个 Base64 字符串。
btoa("JavaScript")       // 'SmF2YVNjcmlwdA=='
atob('SmF2YVNjcmlwdA==') // 'JavaScript'
应用场景
canvas 画布内容生成 base64 编码格式的图片
const canvas = document.getElementById('canvas'); 
const ctx = canvas.getContext("2d");
const dataUrl = canvas.toDataURL();
readAsDataURL()方法把上传的文件转为base64格式的data URI(之前例子已有体现)
img标签和background的 url 属性都支持使用base64 格式的图片,这样做也可以减少 HTTP 请求

FormData

使用FormData我们可以异步上传一个二进制文件,而这个二进制文件,就是我们上面讲的Blob/File对象。

常用方法
  1. append(name, value, filename?): 向FormData对象中添加一个新的键值对。name是字段的名称,value是字段的值,filename是可选的,用于在添加文件时指定文件的名称。

  2. delete(name): 从FormData对象中删除指定名称的键值对。如果成功删除,则返回true;如果指定的键不存在,则返回false

  3. get(name): 获取FormData对象中指定名称的第一个值。如果找到了对应的值,则返回该值;否则,返回null

  4. getAll(name): 获取FormData对象中所有指定名称的值,返回一个数组。如果找到了对应的值,则返回一个包含这些值的数组;如果没有找到,则返回一个空数组。

  5. has(name): 返回一个布尔值,表明FormData对象是否包含指定名称的键值对。如果包含,则返回true;否则,返回false

  6. set(name, value, filename?): 设置FormData对象中指定名称的值。如果该名称已存在,则会覆盖原有的值。filename参数同样用于文件上传时指定文件名,是可选的。

  7. entries(): 返回一个迭代器,包含FormData对象中的每个键值对。这个迭代器可以被用于for...of循环来遍历FormData对象中的所有键值对。

  8. forEach(callback): 遍历FormData对象中的所有键值对,并对每个键值对执行指定的回调函数。回调函数接收三个参数:键名(key)、键值(value)和FormData对象本身(formData)。

  9. keys(): 返回一个迭代器,包含FormData对象中的所有键名。这个迭代器可以被用于for...of循环来获取所有的键名。

  10. values(): 返回一个迭代器,包含FormData对象中的所有值。这个迭代器可以被用于for...of循环来获取所有的值。

文件上传例子

var formData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", 123456); //数字 123456 会被立即转换成字符串 "123456"

// HTML 文件类型 input,由用户选择
formData.append("userfile", fileInputElement.files[0]);

var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值