Base64 和 File、Blob 相互转换

文章目录

  • 前言
  • 一、概念
  • 二、相互转换的工具函数
    • 1. Base64 转 File
    • 2. File 转 Base64
    • 3. Base64 转 Blob
    • 4. Blob 转 Base64

前言

简单介绍一下 Base64 和 File、Blob 对象,及三者之间如何相互转换。


一、概念

  1. Base64

对于一个典型的 Base64 数据 URL,它的格式如下:

data:[<mediatype>][;base64],<data>
# 例如
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...

Base64 编码在网络上的一个常见应用是对二进制数据进行编码。解码和编码 Base64 字符串:

  • btoa():从二进制数据“字符串”创建一个 Base-64 编码的 ASCII 字符串(“btoa”应读作“binary to
    ASCII”)
  • atob():解码通过 Base-64 编码的字符串数据(“atob”应读作“ASCII to binary”)
  1. Blob

Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,从 Blob 中读取内容的方法是使用 FileReader。Blob 对象通常在服务端响应文件流时,前端设置请求头 responseType: ‘blob’,可将响应转换成 Blob,一个 Blob 对象示例如下:

Blob对象

  1. File

File 继承自 Blob,File 对象是 Blob 对象的一个特殊版本,带有一些额外的属性,如 name 和 lastModified。通常文件上传组件如 el-upload 上传成功时得到的是 File 对象,一个 File 对象示例如下:

File对象

二、相互转换的工具函数

1. Base64 转 File

export const base64ToFile = (base64, mime, filename) => {
  let arr = base64.split(',')
  let type = mime || arr[0].match(/:(.*?);/)[1]
  let suffix = mine.split('/')[1]
  let fileName = filename || `未命名.${suffix}`
  let bstr = atob(arr[1])
  let n = bstr.length
  let u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], fileName, { type })
}
  • 正则表达式 /: (.*?);/ 用于匹配以冒号 : 开始,后面跟着任意数量的非分号字符 [^;]*,并以分号 ; 结束的字符串。以上方示例的 base64 字符串为例,会匹配 image/png 部分,即 MIME 类型。
  • atob 函数解码 base64 编码的字符串后,你会得到一个二进制字符串,即每个字符代表一个字节(8位)的原始二进制数据。
  • new Uint8Array(n); // 创建初始化为 0 的,包含 n 个元素的 8 位无符号整型数组。

2. File 转 Base64

function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

fileToBase64 函数时,由于它返回一个 Promise,你需要使用 .then() 或 async/await 来处理结果

3. Base64 转 Blob

转换 Blob 和 File 基本相同,因为 File 就是特殊的 Blob

export const base64ToBlob = (dataurl) => {
  let arr = dataurl.split(',')
  let mime = arr[0].match(/:(.*?);/)[1]
  let bstr = atob(arr[1])
  let n = bstr.length
  let u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
}

4. Blob 转 Base64

function blobToBase64(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onloadend = () => {
      resolve(reader.result);
    };
    reader.onerror = (e) => {
      reject(e);
    };
  });
}
  1. Blob 和 File 相互转换
const file = new File([/* data */], "filename.txt", { type: "text/plain" });
const blob = new Blob();

const blob = new Blob([/* data */], { type: "text/plain" });
const file = new File([blob], "filename.txt", { type: blob.type, lastModified: Date.now() });