JavaScript 提供了一些 API 来处理文件或原始文件数据,例如:File、Blob、FileReader、ArrayBuffer、base64 等。下面就来看看它们都是如何使用的,它们之间又有何区别和联系。
1. Blob
Blob全称为binary large Object 即二进制大对象,他是js中的一个对象,表示原始类似文件的数据。MDN中的解释:
Blob
对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。Blob 表示的不一定是 JavaScript 原生格式的数据。
(1)可以使用Blob()创建一个blob:
new Blob(array, options);
其中两个参数:
- array :可以是ArrayBuffer、ArrayBufferView、Blob、DOMString等对象构成的,将会被放进BLob;
- option :可选的BlobPropertyBag字典。
const obj = { hello: "world" };
const blob = new Blob([JSON.stringify(obj, null, 2)], {
type: "application/json",
});
console.log("blob", blob);
URL.createObjectURL() 将Blob对象转为url地址
2. FIle
File 接口基于
Blob
,继承了 blob 的功能并将其扩展以支持用户系统上的文件。
File
对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中。比如说, FileReader, URL.createObjectURL(), createImageBitmap() (en-US), 及 XMLHttpRequest.send() 都能处理 Blob
和 File
。
3.FileReader
FileReader
对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
// FileReader && Blob/File转化
// FileReader 对象允许web应用程序异步读取存储在用户计算机上的文件内容
export const readBlob = (blob, type) => {
return new Promise((resolve) => {
let reader = new FileReader();
reader.onload = (event) => {
resolve(event.target.result);
};
switch (type) {
case "ArrayBuffer":
// 生成ArrayBUffer
reader.readAsArrayBuffer(blob);
break;
case "DataUrl":
// 生成base64
reader.readAsDataURL(blob);
break;
case "Text":
reader.readAsText(blob, "utf-8");
break;
default:
break;
}
});
};
4.base64
Base64 是一种基于64个可打印字符来表示二进制数据的表示方法。Base64 编码普遍应用于需要通过被设计为处理文本数据的媒介上储存和传输二进制数据而需要编码该二进制数据的场景。这样是为了保证数据的完整并且不用在传输过程中修改这些数据。
在 JavaScript 中,有两个函数被分别用来处理解码和编码 base64 字符串:
atob()
:解码,解码一个 Base64 字符串;btoa()
:编码,从一个字符串或者二进制数据编码一个 Base64 字符串。
btoa("JavaScript") // 'SmF2YVNjcmlwdA=='
atob('SmF2YVNjcmlwdA==') // 'JavaScript'
也可以利用canvas画布中的toDataURL生成base64.
/**
* @param url 图片路径
*/
function getUrlBase64(url) {
return new Promise((resolve, reject) => {
let canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
let img = new Image();
img.crossOrigin = "Anonymous"; //开启img的“跨域”模式
img.src = url;
img.onload = function() {
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0, img.width, img.height); //参数可自定义
const dataURL = canvas.toDataURL("image/jpeg",1); //获取Base64编码
resolve(dataURL);
canvas = null; //清除canvas元素
img = null; //清除img元素
};
img.onerror = function() {
reject(new Error("Could not load image at " + url));
};
});
}
也可以使用FileReader.
// FileReader && Blob/File转化
// FileReader 对象允许web应用程序异步读取存储在用户计算机上的文件内容
export const readBlob = (blob, type) => {
return new Promise((resolve) => {
let reader = new FileReader();
reader.onload = (event) => {
resolve(event.target.result);
};
switch (type) {
case "ArrayBuffer":
// 生成ArrayBUffer
reader.readAsArrayBuffer(blob);
break;
case "DataUrl":
// 生成base64
reader.readAsDataURL(blob);
break;
case "Text":
reader.readAsText(blob, "utf-8");
break;
default:
break;
}
});
};
base64 转 blob
// 将base64转为blob
export function base64toBlob(base64) {
let bstr = window.atob(base64), // 获得base64解码后的字符串
n = bstr.length,
u8arr = new Uint8Array(n); // 新建一个8位的整数类型数组,用来存放ASCII编码的字符串
while (n--) {
u8arr[n] = bstr.charCodeAt(n); // 转换编码后才使用charCodeAt 找到Unicode编码
}
const fileStream = new Blob([u8arr], { type: "text/plain" });
const url = URL.createObjectURL(fileStream);
return url;
}
5.ArrayBuffer
ArrayBuffer对象用来表示通用的、固定长度的原始二进制数据缓冲区。他是一个字节数组,通常在其他语言中称为“byte array”。你不用直接操作ArrayBuffer中的内容;而是通过类型化数组对象或DataView对象来操作,他们会将缓冲区中的数据表示为特定的格式,并通过这些读写缓冲区的内容。
// FileReader && Blob/File转化
// FileReader 对象允许web应用程序异步读取存储在用户计算机上的文件内容
export const readBlob = (blob, type) => {
return new Promise((resolve) => {
let reader = new FileReader();
reader.onload = (event) => {
resolve(event.target.result);
};
switch (type) {
case "ArrayBuffer":
// 生成ArrayBUffer
reader.readAsArrayBuffer(blob);
break;
case "DataUrl":
// 生成base64
reader.readAsDataURL(blob);
break;
case "Text":
reader.readAsText(blob, "utf-8");
break;
default:
break;
}
});
};