File、 Blob、 dataURL 与 docURL相互转换生成


前言

File、 Blob、 dataURL 与 docURL

在日常项目开发中,会有这样的场景:

  • 将用户上传的文件转换为base64编码格式dataURL或Blob对象,上传至服务端
  • 保证资源链接安全性

这里会需要,File、 Blob、 dataURL 与 docURL 相互之间转换生成


一、转换规则说明

文章下述内容中会有使用

文章术语
file(File 对象) blob(Blob 对象) dataURL(base64编码资源路径) docUrl(url:与创建它的窗口中 document 绑定)

  • file -> dataURL | docUrl
  • dataURL -> file | blob
  • blob -> file | dataURL | docUrl
File对象 Blob 对象 base64编码资源路径 url地址与创建它的窗口中 document 绑定 fileLikeToBase64 blobToDocUrl fileLikeToBase64 blobToDocUrl blobToFile base64ToBlob base64ToFile File对象 Blob 对象 base64编码资源路径 url地址与创建它的窗口中 document 绑定

二、转换api

所有方法入参应做一层校验判断是否合法。

校验传入是否合法(简单校验)

这里对于base编码形式的dataURL进行了简单的正则匹配校验,File | Blob 对象进行原型判断

vertifyEntryValue(value: string | File | Blob) {
    if (typeof value === 'string') {
      return /^data:(.*);base64/.test(value);
    } else {
      return value instanceof File || value instanceof Blob;
    }
}

公共方法

_transformBase64: 处理base64编码

/**
   * 处理base64编码
   * @param dataURI base64编码
   * @returns {obj}
   * @returns {obj.mimeString} 资源格式信息  eg. image/png
   * @returns {obj.u8arr} Uint8Array实例
   */
  _transformBase64(dataURI: string) {
    const arr = dataURI.split(',');
    const byteString = atob(arr[1]);
    const mimeString = arr[0].match(/:(.*?);/)![1];

    const ab = new ArrayBuffer(byteString.length);
    const u8arr = new Uint8Array(ab);
    for (let i = 0; i < byteString.length; i++) {
      u8arr[i] = byteString.charCodeAt(i);
    }

    return {
      mimeString,
      u8arr,
    };
  }

1. File转换体系

File构造函数基于Blob,所以此api也适用于blob

1.1 file | blob —> dataURL

FileReader转换是异步过程,使用Promise异步化

// file -> dataURL & blob -> dataURL
fileLikeToBase64(value: File | Blob) {

    return new Promise(
      (
        resolve: (value: string) => void,
        reject: (reason: {
          code: 'custom' | 'system';
          msg: string;
          error?: any;
        }) => void,
      ) => {
        if (!this.vertifyEntryValue(value)) {
          reject({
            code: 'custom',
            msg: this.vertifyErrMsg,
          });
        }

        const fileReader = new FileReader();
        fileReader.readAsDataURL(value);

        fileReader.onload = (e: ProgressEvent<FileReader>) => {
          const dataURL = e.target?.result;

          if (typeof dataURL === 'string') {
            resolve(dataURL);
          } else {
            reject({
              code: 'custom',
              msg: '转换结果不是base64编码dataURL',
            });
          }
        };

        fileReader.onerror = (err) => {
          reject({
            code: 'system',
            msg: 'system error',
            error: err,
          });
        };
      },
    );
  }

1.2 file | blob —> docUrl

  • URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。

  • URL.revokeObjectURL() 静态方法用来释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象。

blobToDocUrl(value: File | Blob) {
    const docUrl = window.URL.createObjectURL(value);

    window.addEventListener('close', () => {
      window.URL.revokeObjectURL(docUrl);
    });

    return docUrl;
}

2. dataURL 转换体系

base64编码形式dataURL使用_transformBase64处理后,使用 File | Blob 构造函数创建实例

2.1 dataURL -> file

base64ToFile(dataURI: string, filename = 'file') {
  const { u8arr, mimeString } = this._transformBase64(dataURI);

  return new File([u8arr], `${filename}.${mimeString.split('/')[1]}`, {
    type: mimeString,
  });
}

2.2 dataURL -> blob

base64ToBlob(dataURI: string) {
  const { u8arr, mimeString } = this._transformBase64(dataURI);

  return new Blob([u8arr], { type: mimeString });
}

3. blob 转换体系

3.1 blob -> dataURL | docUrl

见此文章 File转换体系 部分

3.2 blob -> file

利用File Api讲blob转成File对象

blobToFile(value: Blob, filename = 'file') {
  return new window.File([value], filename, { type: value.type });
}
  • 30
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值