心血来潮,复习下可以不会但不能不知道的Blob

1,796 阅读4分钟

你好呀,我是你们的老倒霉蛋wangly。上周末没有去更新文章都在谋划自己的新东西。除了写自己的组件库就是在复习一些知识点。不得不说,现在找工作太难了。这篇文章主要是复习下大文件切片上传的Blob

本文属于笔记文,不深入。只做一个了解。

什么是Blob

借用Mdn web docs文档的描述:

Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。

Blob的英文翻译语义二进制大对象,顾名思义,它是一个承载二进制的大型集合容器。再简单点Blob其实就是一堆二进制的数据堆。可以使用File的方式去进行一些操作,从上文引用中也提到了,File其实是Blob的子类。继承Blob的同时进行了延申。因此File也算是一个异种Blob。所以,Blob有的APIFile同样全部具备。

实例化和参数

可以通过new Blob(array, option)来实例化一个Blob对象。其中有两个参数分别来干什么的,有什么用?

  • array:默认为空,第一个参数需要你传递一个缓存形式的数组变量。在实例化过程中,会将数组中的缓存内容放金Blob,从而生成一个Blob对象。
  • opiton:它需要你传递一个对象,对象中包含一个type的属性来声明Blob的数据类型。它看起来是这样的。默认情况下type的值为空null | ""
    interface option {
      type: string
    }
    
const domBuffer = ['<a id="a">dom blob !!!!</a>']
const domBlob = new Blob(domBuffer, {type : 'text/html'})
console.log(domBlob)

将blob实例打印出来,就是下面的一个形式

属性说明

从上面的Blob实例可以看到其中包含两个属性type, size属性。它们分别代表什么含义?

  • type:type代表着Blob的二进制内容的类型,这个在声明Blob的时候就被声明了。
  • size:size表示Blob的内容大小,单位为字节

实例方法

可以观察到,Blob下面是有默认的方法给我们调用的。其中它们究竟起了什么作用呢?

slice方法

slice截取方法我们在其他地方也看到过,比如数组。两者的原理其实相似。只是一个用来操作数组,一个用来操作Blob。它们都会返回一个新的数据。

// 开始截取10字节
const slice10 = domBlob.slice(0, 10)

我们通过以上尝试,传入start, end的参数产生了一个新的Blob,新的Blob为自己切割出来大小的字节对象。虽然截取了出来,但是好像有什么不对。type好像丢失了?新的Blob并没有一个类型。那么我们就需要将第三个参数contentType传递进来,定义一个类型声明。

const slice10 = domBlob.slice(0, 10, 'text')

text方法

text文本方法会通过promise的方式将Blob的内容返回出来。

domBlob.text().then(text => {
  console.log(text)
})

stream方法

使用stream方法可以将Blob以一个stream对象的形式展现出来。可以通过stream对象的方法进行一些行为操作。

const stream = domBlob.stream()
console.log(stream)

arrayBuffer方法

通过arrayBuffer方法,以二进制的形式包含 blob 中的数据在arrayBuffer方法展示出来。

const stream = domBlob.arrayBuffer().then(buffer => {
  console.log(buffer)
})

文件切片

原理就是将文件作为一个文件,切成若干个文件。然后通过与后端交互将二进制文件发送给后端。需要注意几个点:

  • 切片是否正常
  • 上传的序列必须不能乱
  • 避免重复的文件上传
  • 当上传完成,后端合并验证字节。

获取文件

// 文件回调
  private handleUpload(e: Event) {
    const [file] = (e.target as any).files
    if (!file) return
    this.file = file
    console.log(file)
    this.createFileChunk(file)
  }

切片

// 文件切片
  createFileChunk(file:File, _size: number = 500) {
    // 文件大小
    const fileSize: number = file.size
    // 开始字节
    let startSize: number = 0
    // 切片计算
    const chunkCount: number = Math.ceil(fileSize / _size)
    // 计算页码
    let page: number = 1
    // 切片列表
    const fileList: Array<Blob | File> = []
    while (page <= chunkCount) {
      const chunkFile:File | Blob = file.slice(startSize, startSize + _size)
      fileList.push(chunkFile)
      startSize = startSize + _size
      page++
    }
    console.log('切片后的file:', fileList)
    this.fileList = fileList
    this.start = startSize
  }

总结

Blob在前端传统业务中,几乎看不见。但是随着业务深入。涉及到大文件的交互时。二进制的便捷性就体现出来了。因为二进制是可递增的。只要二进制不丢失。那么,对于文件的完整性是有保证的。本篇文章主要是对Blob的学习文章。没有做过多的深入。只是为了在以后碰到类似的问题有点印象。

阅读参考的文章:

前端大文件上传@橙红年代

点击跳转

字节跳动面试官:请你实现一个大文件上传和断点续传@ yeyan1996:

点击跳转

MDN Blob Web Api

点击跳转

有好的机会可以推荐我哦。