new Blob() 和 new File() 详解:前端处理二进制数据的利器

6,508 阅读9分钟

在前端开发项目中,处理和操作二进制数据是非常常见的任务,无论是上传文件、处理图像、音频还是视频,都需要一种灵活而强大的工具来应对。JavaScript中的new Blob()new File()构造函数正是这样的工具,它们提供了处理和操作二进制数据的能力,让前端工程师可以更好地应对各种需求。本文将深入探讨这两个构造函数的使用方法以及它们在前端开发中的实际应用。

了解 new Blob()

什么是 Blob?

Blob(Binary Large Object,二进制大对象)是JavaScript中用于表示二进制数据块的标准化接口。它可以包含各种类型的数据,包括文本、图像、音频、视频和其他文件格式的数据。Blob对象通常用于以下情况:

  • 存储从不同来源获取的数据,如用户上传的文件、服务器响应的文件、Canvas绘制的图像等。
  • 在客户端进行数据处理和转换,例如对图像进行裁剪、添加水印,或者将文本数据编码为不同格式。
  • 将数据发送到服务器或在客户端缓存数据,以提高Web应用的性能和效率。

创建 Blob 对象

要创建一个 Blob 对象,我们可以使用 new Blob() 构造函数。这个构造函数接受一个包含数据的数组作为其第一个参数,还可以接受一个配置对象作为其第二个参数,配置对象用于指定 Blob 对象的类型(MIME 类型)以及其他属性。下面是一个创建包含文本数据的 Blob 对象的示例:

const text = "Hello, Blob!";
const blob = new Blob([text], { type: "text/plain" });

在这个示例中,我们首先定义了一个包含文本数据的字符串 text,然后使用 new Blob() 构造函数创建了一个包含这个文本数据的 Blob 对象。我们还通过配置对象 { type: "text/plain" } 指定了 Blob 对象的类型为纯文本。

Blob 的构造函数参数

new Blob() 构造函数的第一个参数是一个包含数据的数组,这个数组可以包含多个数据块,每个数据块可以是字符串、二进制数据(例如 Uint8Array)或其他 Blob 对象。这使得我们可以很灵活地构建包含多个数据块的 Blob 对象。

下面是一个示例,演示如何创建一个包含多个数据块的 Blob 对象:

const data1 = "First part of data";
const data2 = new Uint8Array([1, 2, 3, 4, 5]);
const data3 = new Blob(["Another text"], { type: "text/plain" });

const blob = new Blob([data1, data2, data3]);

在这个示例中,我们创建了一个包含文本、Uint8Array 和另一个 Blob 对象的 Blob 对象。Blob 会将这些数据块按顺序组合在一起。

Blob 配置选项

new Blob() 构造函数的第二个参数是一个可选的配置选项对象,用于指定 Blob 对象的类型以及其他元数据。配置选项的常见属性包括:

  • type:指定 Blob 的 MIME 类型。这可以帮助浏览器正确处理 Blob 数据。例如,如果要创建一个包含 PNG 图像数据的 Blob 对象,可以将 { type: "image/png" } 传递给构造函数。

  • endings:指定文本 Blob 的换行符类型。可以是 "native"(默认,表示使用操作系统的本机换行符),也可以是 "transparent"(表示使用 \n 换行符)。

下面是一个示例,演示如何使用配置选项创建一个包含 JSON 数据的 Blob 对象:

const jsonData = { name: "John", age: 30 };
const jsonBlob = new Blob([JSON.stringify(jsonData)], { type: "application/json" });

在这个示例中,我们创建了一个包含 JSON 数据的 Blob 对象,并通过配置选项指定了其类型为 "application/json"

Blob 的大小

要获取 Blob 对象的大小,可以使用其 size 属性:

const blob = new Blob(["Hello, Blob!"], { type: "text/plain" });
const size = blob.size; // 获取 Blob 对象的大小,以字节为单位

了解 new File()

什么是 File?

File 对象是 Blob 对象的扩展,它继承了 Blob 对象的所有特性,同时还包含了有关文件的更多信息,如文件名和最后修改日期。File 对象通常用于表示用户选择的文件,例如在文件上传表单中。

创建 File 对象

要创建一个 File 对象,我们可以使用 new File() 构造函数,这个构造函数接受三个参数:

  1. 一个包含数据的数组,这个数组可以是包含文本、二进制数据或其他 Blob 对象的数组。
  2. 文件名,用于表示文件的名称,通常包括文件扩展名。
  3. 可选的文件选项对象,用于指定文件的类型和其他属性。

下面是一个创建 File 对象的示例:

const blob = new Blob(["Hello, File!"], { type: "text/plain" });
const fileName = "hello.txt";
const file = new File([blob], fileName);

在这个示例中,我们首先创建了一个包含文本数据的 Blob 对象,然后使用 new File() 构造函数将其转换为 File 对象,并指定了文件名为 "hello.txt"

File 对象的属性

File 对象包含了 Blob 对象的所有属性,以及以下额外的属性:

  • name:表示文件的名称,通常包括文件扩展名。
  • lastModified

:表示文件的最后修改时间戳。

这些属性使得 File 对象更适合用于表示用户选择的文件,因为它们包含了文件的关键信息。

Blob 对象和 File 对象的用途

Blob 对象和 File 对象在前端开发中有多种用途,下面将介绍一些常见的应用场景。

1. 文件上传

在 Web 应用程序中,用户通常需要上传文件,例如图像、文档或音频文件。在将文件上传到服务器之前,您通常需要在客户端创建一个 Blob 对象或 File 对象以存储文件数据。

const fileInput = document.getElementById("file-input");
fileInput.addEventListener("change", () => {
  const file = fileInput.files[0];
  // 将 File 对象或 Blob 对象发送到服务器
});

在上面的示例中,我们监听了一个文件输入元素的变化事件,获取用户选择的文件,然后可以将 File 对象或 Blob 对象发送到服务器以进行文件上传。

2. 图像处理

在某些情况下,您可能需要在客户端对图像进行处理,例如调整大小、添加水印或应用滤镜。通常,您可以使用 Canvas API 处理图像数据,然后将结果存储在 Blob 对象或 File 对象中。

const image = new Image();
image.src = "image.jpg";

image.onload = () => {
  const canvas = document.createElement("canvas");
  canvas.width = 300;
  canvas.height = 200;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(image, 0, 0, canvas.width, canvas.height);

  canvas.toBlob((blob) => {
    // 处理后的图像数据存储在 blob 中
  }, "image/jpeg");
};

在这个示例中,我们加载了一个图像,将其绘制到 Canvas 上,然后使用 Canvas 的 toBlob() 方法将 Canvas 上的内容保存为一个 Blob 对象。这个 Blob 对象包含了经过处理的图像数据。

3. 音频和视频处理

类似于图像处理,您可以使用 Blob 对象或 File 对象来处理音频和视频数据。例如,您可以录制用户的音频输入,并将录制的音频数据存储在 Blob 对象中,然后进行后续处理或上传。

navigator.mediaDevices.getUserMedia({ audio: true })
  .then((stream) => {
    const mediaRecorder = new MediaRecorder(stream);
    const audioChunks = [];

    mediaRecorder.ondataavailable = (event) => {
      if (event.data.size > 0) {
        audioChunks.push(event.data);
      }
    };

    mediaRecorder.onstop = () => {
      const audioBlob = new Blob(audioChunks, { type: "audio/wav" });
      // 处理录制的音频数据存储在 audioBlob 中
    };

    // 开始录制
    mediaRecorder.start();

    // 停止录制
    setTimeout(() => {
      mediaRecorder.stop();
    }, 5000); // 录制 5 秒钟
  })
  .catch((error) => {
    console.error("Error accessing microphone:", error);
  });

在上面的示例中,我们使用 getUserMedia() 获取用户的音频输入流,然后使用 MediaRecorder 录制音频数据。录制的数据块被存储在一个数组中,然后使用 Blob 对象将其组合为一个 Blob 对象。

4. 缓存资源

在一些情况下,您可能希望在客户端缓存一些资源文件,以便在将来更快地加载它们。您可以使用 Blob 对象或 File 对象来存储这些资源。

// 下载并缓存资源
fetch("https://example.com/resource.jpg")
  .then((response) => response.blob())
  .then((blob) => {
    // 将 Blob 对象存储在 IndexedDB 或 LocalStorage 中以供将来使用
  })
  .catch((error) => {
    console.error("Error fetching resource:", error);
  });

// 在以后的某个时间加载已缓存的资源
// 从 IndexedDB 或 LocalStorage 中获取 Blob 对象

在上面的示例中,我们使用 fetch() 函数下载资源文件,将其作为 Blob 对象返回,并将 Blob 对象存储在本地以供将来使用。

5. 动态生成文件

有时,您可能需要在客户端动态生成文件,例如生成 PDF 文件或 CSV 文件,并提供给用户下载。Blob 对象和 File 对象非常适合用于这些用途。

// 生成并下载 CSV 文件
function generateCSV() {
  const data = [["Name", "Age"], ["Alice", 25], ["Bob", 30]];
  const csvContent = data.map((row) => row.join(",")).join("\n");
  const csvBlob = new Blob([csvContent], { type: "text/csv" });

  const downloadLink = document.createElement("a");
  downloadLink.href = URL.createObjectURL(csvBlob);
  downloadLink.download = "data.csv";
  downloadLink.click();
}

// 调用生成 CSV 函数
generateCSV();

在这个示例中,我们定义了一个 generateCSV() 函数,它生成一个包含 CSV 数据的 Blob 对象,然后创建一个带有下载链接的 <a> 元素,以便用户可以单击下载文件。

Blob 对象和 File 对象的相互转换

在某些情况下,您可能需要将 Blob 对象转换为 File 对象,或者将 File 对象转换为 Blob 对象。这可以通过以下方式实现:

Blob 转换为 File

要将 Blob 对象转换为 File 对象,您可以使用 new File() 构造函数,传递 Blob 对象、文件名和可选的文件选项作为参数。这样,您可以为 Blob 对象添加文件名和其他文件相关信息。

const blob = new Blob(["Hello, Blob!"], { type: "text/plain" });
const fileName = "hello.txt";
const file = new File([blob], fileName);

File 转换为 Blob

File 对象本质上是 Blob 对象的扩展,因此 File 对象可以直接用作 Blob 对象。无需进行显式转换。

const file =

 /* 获取 File 对象的方法 */;
const blob = file;

注意,虽然 File 对象包含更多的文件相关信息,但 Blob 对象可以用于处理和传输二进制数据,而无需关心文件的详细信息。

Blob 对象和 File 对象的总结

Blob 对象和 File 对象是处理二进制数据的重要工具,它们可以用于多种用途,从文件上传到图像和音频处理,再到资源缓存和动态生成文件。通过 new Blob()new File() 构造函数,你可以轻松创建包含各种类型数据的 Blob 对象和 File 对象,并使用配置选项指定元数据。这些对象在前端开发中发挥着关键作用,帮助开发人员处理和操作二进制数据,满足各种需求。无论您的前端开发项目涉及哪种类型的二进制数据,Blob 对象和 File 对象都是强大而灵活的工具,值得深入学习和应用。希望本文对你理解 Blob 对象和 File 对象以及如何使用它们有所帮助!