JS 的二进制家族:base64、File、Blob、ArrayBuffer 的关系

7,842 阅读2分钟

作为前端开发,虽然不需要关系二进制数据,但是是不是有时候上传图片的,下载文件等会base64、File、Blob、ArrayBuffer、Buffer傻傻分不清楚

下面来一一介绍:

一、File对象

定义: 一个FileList 对象通常来自于一个 HTML input 元素的 files 属性,你可以通过这个对象访问到用户所选择的文件,或者拖拽文件

<input type="file" id="upload" @change="choose"> 当你选择一张图片时,$("#upload").files 会返回一个对象

File 对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中

二、base64

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

使用场景:

  • 对证书来说,特别是根证书,一般都是作Base64编码的,因为它要在网上被许多人下载。
  • 电子邮件的附件一般也作Base64编码的,因为一个附件数据往往是有不可见字符的。
  • 网页中一些小图片可以直接以base64编码的方式嵌入。不用再用链接请求消耗资源。

三、ArrayBuffer

定义:ArrayBuffer对象、TypedArray对象、DataView对象是JavaScript操作二进制数据的一个接口。

不能设置MIME类型,是原始的二进制数据缓冲区,无法直接读取或写入,需要通过具体的视图来读取或写入,即TypedArray对象或DataView对象对内存大小进行读取或写入

四、Blob:

定义:Blob 对象表示一个不可变、原始数据的类文件对象

存储二进制文件容器,可设置MIME类型

Blob(binary large object),二进制类文件大对象,是一个可以存储二进制文件的“容器”,HTML5中的Blob对象除了存放二进制数据外还可以设置这个数据的MIME类型【标识邮件和http请求的网络数据格式】。

File接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。

1. 借助FileReader转成其他格式

如果想要读取Blob或者文件对象并转化为其他格式的数据,可以借助FileReader对象的API进行操作

  • FileReader.readAsText(Blob):将Blob转化为文本字符串
  • FileReader.readAsArrayBuffer(Blob): 将Blob转为ArrayBuffer格式数据
  • FileReader.readAsDataURL(): 将Blob转化为Base64格式的Data URL
choose() {
  let file = this.$refs.upload.files[0];
  const reader = new FileReader();
  reader.onload = function () {
    const content = reader.result;
    console.log('ArrayBuffer结果:',content);
  }
  reader.readAsArrayBuffer(file);
}

2. Blob URL 用于文件上传下载

我们可以通过window.URL.createObjectURL,接收一个Blob(File)对象,将其转化为Blob URL,然后赋给 a.download属性,然后在页面上点击这个链接就可以实现下载了

<!-- html部分 -->
<a id="h">点此进行下载</a>
<!-- js部分 -->
<script>
  var blob = new Blob(["Hello World"]);
  var url = window.URL.createObjectURL(blob);
  var a = document.getElementById("h");
  a.download = "helloworld.txt";
  a.href = url;
</script> 

3. blob.slice 分段上传

  • 通过Blob.slice(start,end)可以分割大Blob为多个小Blob
  • xhr.send是可以直接发送Blob对象的

五、Buffer

Buffer是Node.js提供的对象,前端没有。 它一般应用于IO操作,例如接收前端请求数据时候,可以通过以下的Buffer的API对接收到的前端数据进行整合(这里就不介绍了)

互转

1. file对象转base64

  let reader = new FileReader();
  reader.readAsDataURL(file[0])
  console.log(reader)

2. base64 转成blob 上传

function dataURItoBlob(dataURI) {  
    var byteString = atob(dataURI.split(',')[1]);  
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];  
    var ab = new ArrayBuffer(byteString.length);  
    var ia = new Uint8Array(ab);  
    for (var i = 0; i < byteString.length; i++) {  
        ia[i] = byteString.charCodeAt(i);  
    }  
    return new Blob([ab], {type: mimeString});  
}

2. blob 转成ArrayBuffer

let blob = new Blob([1,2,3,4])
let reader = new FileReader();
reader.onload = function(result) {
    console.log(result);
}
reader.readAsArrayBuffer(blob);

3. buffer 转成blob

let blob = new Blob([buffer])

4. base64 转 file

const base64ConvertFile = function (urlData, filename) { // 64转file
  if (typeof urlData != 'string') {
    this.$toast("urlData不是字符串")
    return;
  }
  var arr = urlData.split(',')
  var type = arr[0].match(/:(.*?);/)[1]
  var fileExt = type.split('/')[1]
  var bstr = atob(arr[1])
  var n = bstr.length
  var u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], 'filename.' + fileExt, {
    type: type
  });
}

总结

  1. File对象从input选择或者拖拽中产生 files[0]
  2. File对象继承Blob,是种特殊的blob
  3. blob 是二进制存储容器
    • window.URL.createObjectURL(blob)可以把一个blob转成blobURL,用作图片显示,文件下载(不能再服务器上存储,只能在浏览器使用)
    • blob.slice 分段上传
    • FileReader 转成文本、ArrayBufffer、DATA url等类型
  4. ArrayBufffer 是原始存储二进制的缓冲区,相当于定义了一块空间
  5. 通过TypeArray 生成内存的视图,代表确定类型的二进制数据
  6. DataView也是生成视图的,可以自定义格式和字节序

推荐文章: 聊聊JS的二进制家族 二进制数组