JavaScript 中,File、Blob、Base64 和 ArrayBuffer 不同的用途和转换方法。
- 图示:
Blob:
- 概念:代表不可变的原始数据二进制块,可以是图片、视频等数据。
- 用途:用于处理二进制数据、文件上传和下载、创建文件对象。
// 创建一个 Blob 对象
const blob = new Blob(["Hello, world!"], { type: "text/plain" });
// 创建对象 URL
const url = URL.createObjectURL(blob);
//从 Blob 转换为 File:
const file = new File([blob], "hello.txt", { type: "text/plain", lastModified: new Date() });
//从 Blob 转换为 Base64:
const reader = new FileReader();
reader.onloadend = () => {
const base64 = reader.result.split(",")[1]; // Remove the data URL prefix
console.log(base64);
};
reader.readAsDataURL(blob);
//从 Blob 转换为 ArrayBuffer:
const reader = new FileReader();
reader.onload = (e) => {
const arrayBuffer = e.target.result;
console.log(arrayBuffer);
};
reader.readAsArrayBuffer(blob);
File:
- 概念:File 是 Blob 的子类,代表用户上传的文件对象,包含文件名、文件类型等信息。
- 用途:用于表示文件对象,通常来自用户输入的文件(如通过 )。
//从 File 转换为 Blob:
const file = document.querySelector('input[type="file"]').files[0];
const blob = new Blob([file], { type: file.type });
//从 File 转换为 base64:
const reader = new FileReader();
reader.onload = function (event) {
// 获取 Base64 编码的结果
const base64String = event.target.result.split(",")[1];
console.log(base64String);
};
reader.readAsDataURL(file);
//从 File 转换为 ArrayBuffer:
const reader = new FileReader();
reader.onload = (e) => {
const arrayBuffer = e.target.result;
console.log(arrayBuffer);
};
reader.readAsArrayBuffer(file);
Base64:
- 概念:一种编码方式,将二进制数据编码为 ASCII 字符串。
- 用途:用于在 URL 或 HTML 中嵌入小的图像、文件,方便传输,但数据会变得更大。
// 将文本编码为 Base64
const base64 = btoa("Hello, world!");
// 解码 Base64
const decoded = atob(base64);
//从 Base64 转换为 Blob:
const base64 = "data:text/plain;base64,SGVsbG8sIHdvcmxkIQ==";
const response = await fetch(base64);
const blob = await response.blob();
//从 Base64 转换为 ArrayBuffer:
const base64 = "SGVsbG8sIHdvcmxkIQ==";
const binaryString = atob(base64);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
const arrayBuffer = bytes.buffer;
console.log(arrayBuffer);
Buffer:
- 概念:在 Node.js 环境中使用的用于处理原始二进制数据的对象。提供了更多用于操作和管理二进制数据的方法,特别适合处理文件系统和网络流数据。
- 用途:用于处理二进制数据的类,特别适合处理文件、网络流、加密操作等。常用于文件系统操作、网络请求和响应处理等 Node.js 环境中。
- 特点:
- 高效:Buffer 在 Node.js 中用于处理二进制数据,提供了高效的内存管理。自身具有丰富的方法来直接操作数据。
- 方法丰富:提供了很多内置的方法用于操作二进制数据,如 write, slice, toString, fill 等。
- Node.js 专用:是 Node.js 的核心部分,不直接在浏览器中使用。
// 创建一个 Buffer 对象,包含字符串数据
const buffer = Buffer.from("Hello, world!", "utf-8");
// 输出 Buffer 内容
console.log(buffer); // 输出: <Buffer 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21>
// 将 Buffer 转换为字符串
console.log(buffer.toString()); // 输出: Hello, world!
ArrayBuffer:
- 概念:是一个用于表示通用、固定长度的原始二进制数据缓冲区。提供原始的二进制数据缓冲区,通常用于处理和传输数据。
- 用途:用于 Web 开发中的二进制数据处理,如从 Blob 读取数据、处理 WebSockets 的二进制数据等。
- 特点:ArrayBuffer 本身是不可变的。它是二进制数据的原始缓冲区,不能直接进行读写操作。
- 视图: 可以通过不同的视图(TypedArray)(如 Uint8Array, Int16Array, Float32Array 等)来读写 ArrayBuffer 中的数据。
- Web API:是 Web 标准的一部分,广泛用于 Web 应用程序中、用于浏览器环境。
// 创建一个 16 字节的 ArrayBuffer
const buffer = new ArrayBuffer(16);
// 创建一个视图来读取和写入数据
const view = new Uint8Array(buffer);
// 设置数据
view[0] = 42;
// 读取数据
console.log(view[0]); // 输出: 42
//从 ArrayBuffer 转换为 Blob:
const blob = new Blob([arrayBuffer], { type: "application/octet-stream" });
//从 ArrayBuffer 转换为 Base64:
const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
console.log(base64);
常用转换函数
base64ToFile
function base64ToFile(base64String, fileName) {
// 从 Base64 字符串中提取 MIME 类型和编码数据
const [header, base64Data] = base64String.split(",");
const mime = header.match(/:(.*?);/)[1];
// 解码 Base64 数据
const binaryString = atob(base64Data);
const arrayBuffer = new ArrayBuffer(binaryString.length);
const uint8Array = new Uint8Array(arrayBuffer);
// 将解码的数据填充到 Uint8Array 中
for (let i = 0; i < binaryString.length; i++) {
uint8Array[i] = binaryString.charCodeAt(i);
}
// 创建 Blob 对象
const blob = new Blob([uint8Array], { type: mime });
// 创建 File 对象
return new File([blob], fileName, { type: mime });
}
dataURLtoBlob
/**
* base64编码的dataURL转化为Blob不可变二进制数据
* @param {String} dataURL base64编码的dataURL字符串,格式比如 data:image/png;base64,经过base64编码的字符串
* @result {Object} 返回值为Blob对象
*/
export function dataURLtoBlob(dataURL) {
//获取MIME类型
let mime = dataURL.split(",")[0].split(":")[1].split(";")[0];
//对经过base64编码的数据进行解码
let byteString = window.atob(dataURL.split(",")[1]);
// 创建内存
let arrayBuffer = new ArrayBuffer(byteString.length);
// 生成内存的视图,通过TypeArray对象操作二进制
let typeArray = new Uint8Array(arrayBuffer);
// 遍历二进制数据通过typeArray对象将数据存储到arrayBuffer对象中
for (let i = 0; i < byteString.length; i++) {
typeArray[i] = byteString.charCodeAt(i);
}
// 生成blob数据
return new Blob([typeArray], { type: mime });
}
binaryToDataURL
/**
* 将binary(二进制)数据转化为base64编码的DataURL字符串
* @param {Object} data Blob类型或file类型的数据
* @param {Function} fn 回调函数
*/
export function binaryToDataURL(data, fn) {
if (window.FileReader) {
const file = new FileReader();
//如果data为空返回null
if (data == undefined) return fn(null);
file.onload = function (e) {
fn(e.target.result);
};
file.readAsDataURL(data);
}
}
导出 csv
/**
* 前端导出csv格式表格(没有表格线),但是不支持合并表格和图片导出,并且解决了csv文件过大下载失败的问题
* @param {String} str 标题字符串,格式: '标题1,标题2,标题3...'
* @param {array} dataList 数据数组, 格式: [{},{},{}...]
* @param {String} fileName 保存文件名
*/
export function exportCSV(str, dataList, fileName) {
fileName = fileName || new Date().getTime();
//标题
str = str + "\n";
//增加\t为了不让表格显示科学计数法或者其他格式
for (let i = 0; i < dataList.length; i++) {
for (let item in dataList[i]) {
str += `${dataList[i][item] + "\t"},`;
}
str += "\n";
}
//在字符串前面添加\ufeff解决构造Blob中文乱码问题
str = "\ufeff" + str;
//构造Blob数据(text/plain纯文本格式)
let blob = new Blob([str], { type: "text/plain;charset=utf-8" });
//创建url和下载标签
let url = window.URL.createObjectURL(blob);
let link = document.createElement("a");
link.href = url;
link.download = fileName + ".csv";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
//释放url对象
window.URL.revokeObjectURL(url);
}
导出文件
/**
* 下载二进制数据(ajax请求需设置responseType: "blob"或"arraybuffer")
* @param {Blob} data 二进制数据 必填
* @param {string} fileName 文件名称 必填
* @param {string} type 文件后缀 必填
*/
export function saveAsBinary(data, fileName, type) {
if (!fileName || !type) {
console.error("please set file name and file type");
}
// 转换成blob数据
let blob = null;
if (isBlob(data)) {
blob = data;
} else if (isArrayBuffer(data)) {
blob = new Blob([data], { type: FileAndMIME[type] });
} else {
return;
}
// ie浏览器兼容
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, `${fileName}.${type}`);
} else if (window.URL) {
//创建a标签
const link = document.createElement("a");
//获取body元素
const body = document.querySelector("body");
//创建url链接
link.href = window.URL.createObjectURL(blob);
//重命名
link.download = `${fileName}.${type}`;
//火狐需要隐藏标签
link.style.display = "none";
//插入到body中
body.appendChild(link);
//触发下载
link.click();
//移除a标签
body.removeChild(link);
//释放url对象
window.URL.revokeObjectURL(link.href);
}
}
常用 office 文件对应的 MIME TYPE 和后缀
export const FileAndMIME = {
".doc": "application/msword",
".dot": "application/msword",
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".dotx": "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
".docm": "application/vnd.ms-word.document.macroEnabled.12",
".dotm": "application/vnd.ms-word.template.macroEnabled.12",
".xls": "application/vnd.ms-excel",
".xlt": "application/vnd.ms-excel",
".xla": "application/vnd.ms-excel",
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
".xltx": "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
".xlsm": "application/vnd.ms-excel.sheet.macroEnabled.12",
".xltm": "application/vnd.ms-excel.template.macroEnabled.12",
".xlam": "application/vnd.ms-excel.addin.macroEnabled.12",
".xlsb": "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
".ppt": "application/vnd.ms-powerpoint",
".pot": "application/vnd.ms-powerpoint",
".pps": "application/vnd.ms-powerpoint",
".ppa": "application/vnd.ms-powerpoint",
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
".potx": "application/vnd.openxmlformats-officedocument.presentationml.template",
".ppsx": "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
".ppam": "application/vnd.ms-powerpoint.addin.macroEnabled.12",
".pptm": "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
".potm": "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
".ppsm": "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
};
总结
- File 和 Blob 用于处理文件和二进制数据。
- Base64 用于编码和嵌入二进制数据。适合小量数据嵌入。
- ArrayBuffer 用于处理原始二进制数据缓冲区。
- Buffer 主要用于 Node.js 环境处理原始数据。