File,Blob,Base64之间的转换

在前端开发中,经常会有对文件的操作,会用到Flie,Blob,Base64等文件对象类型,通过查阅MDN弄清了他们之间的关系,和它们之间的转换方法,妈妈再也不用担心文件对象操作的问题了!

File对象

通常情况下, File对象是来自用户在一个 <input> 元素上选择文件后返回的 FileList 对象,也可以是来自由拖放操作生成的 DataTransfer 对象,或者来自 HTMLCanvasElement 上的 mozGetAsFile() API

File 对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中。比如说, FileReader, URL.createObjectURL(), createImageBitmap(), 及 XMLHttpRequest.send() 都能处理 BlobFile

通过input获取文件对象(详见:在web应用程序中使用文件)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="app">
        <input type="file" id="file">
    </div>
</body>
<script>
    var inputDom = document.getElementById('file')
    inputDom.addEventListener('change', (event) => {
        console.log('文件对象', event.target.files[0]);
    });
</script>
</html>

在这里插入图片描述
在这里插入图片描述

Blob对象

Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。

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

要从其他非blob对象和数据构造一个 Blob,请使用 Blob() 构造函数。

所以我们从File对象要得到Blob对象,可用Blob构造函数。

//接上面的代码
var inputDom = document.getElementById('file')
inputDom.addEventListener('change', (event) => {
    console.log('文件对象', event.target.files[0]);
    var fileObj =  event.target.files[0]
    var blobObj = new Blob([fileObj],{type:fileObj.type})
    console.log('Blob对象', blobObj);
});

在这里插入图片描述
在这里插入图片描述

Base64

Base64 是一组相似的二进制到文本(binary-to-text)的编码规则,使得二进制数据在解释成 radix-64 的表现形式后能够用 ASCII 字符串的格式表示出来。Base64 这个词出自一种 MIME 数据传输编码。

readAsDataURL 方法会读取指定的 BlobFile 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。

//接上面的代码
var reader = new FileReader();
reader.onload = function (evt) {
    console.log('Base64', evt.target.result);
};
reader.readAsDataURL(fileObj);

在这里插入图片描述
可以看出转base64后编码尺寸增加。

每一个Base64字符实际上代表着6比特位。因此,3字节(一字节是8比特,3字节也就是24比特)的字符串/二进制文件可以转换成4个Base64字符(4x6 = 24比特)。

这意味着Base64格式的字符串或文件的尺寸约是原始尺寸的133%(增加了大约33%)。如果编码的数据很少,增加的比例可能会更高。例如:字符串"a"的length === 1进行Base64编码后是"YQ=="的length === 4,尺寸增加了300%。

所以在实际使用中,一般小图标可用base64来展示,大的文件放在服务器,通过url形式展示。

问题:如何从Base64转到blob?

通过查阅资料得到了下面的方法

function dataURLtoBlob(dataurl) {
    //传入base64编码
    var arr = dataurl.split(','),//拆分
        mime = arr[0].match(/: (.*?);/)[1],//获取类型
        bstr = atob(arr[1]), //获取二进制
        n = bstr.length, //获取长度
        u8arr = new Uint8Array(n);//获取二进制编码数组
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);//返回指定位置的字符的 Unicode 编码
    }//获取TypedArray
    return new Blob([u8arr], { type: mime });//构造函数创建Blob
}

以前用这个方法并不知道其中的道道,通过断点调试及查阅资料可以得知如下解析:

  • 通过split方法把base64分成两部门,头(包含源文件类型信息),ASCII 字符串(文件数据)部分。
    在这里插入图片描述

  • arr[0].match(/: (.*?);/)[1]通过正则获取文件类型。
    在这里插入图片描述

  • atob() 函数能够解码通过base-64编码的字符串数据,获取二进制数据“字符串”。

  • n = bstr.length, u8arr = new Uint8Array(n);new Uint8Array(length); // 创建初始化为0的,包含length个元素的无符号整型数组,就是说把二进制数据“字符串”拆开放进u8arr数组中。
    在这里插入图片描述

  • while (n--) { u8arr[n] = bstr.charCodeAt(n); }调用charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数。获取到的是一个类型化数组(TypedArray)对象描述了一个底层的二进制数据缓冲区(binary data buffer)的一个类数组视图(view)。相当于ArrayBuffer实例。
    在这里插入图片描述

  • new Blob([u8arr], { type: mime });用构造函数创建Blob对象,完成了Base64到Blob的转换
    在这里插入图片描述

总结

  • Blob对象表示一个不可变、原始数据的类文件对象。

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

  • 可以用Blob构造函数把Flie对象转换为Blob对象,可以通过FileReader.readAsDataURL()方法获取文件的data:URL格式的字符串(base64编码)。

  • base64转Blob需先将其拆分,将ASCII 字符串转换为TypedArray,再通过Blob构造函数创建Blob对象。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值