File API:解锁前端文件操作的强大能力

146 阅读4分钟

传统的文件上传控件(<input type="file">)功能有限,用户体验不佳,无法满足现代 Web 应用的需求。幸运的是,HTML5 提供了强大的 File API,它允许 JavaScript 在客户端读取和操作本地文件,极大地丰富了文件处理的能力。本文将详细介绍 File API 的核心组件和使用方法,帮助你更好地理解和应用这一强大的工具。

一、File API 简介

HTML5 的 File API 提供了一组接口,允许 JavaScript 在客户端读取和操作本地文件。这些接口包括:

  • File:表示单个文件,提供了文件的基本信息,如文件名、大小、类型等。
  • FileList:一个类数组对象,包含多个 File 对象,通常用于处理多文件上传。
  • FileReader:用于异步读取文件内容,支持多种格式,如文本、二进制、Data URL 等。
  • Blob:表示二进制数据,File 对象继承自 Blob,因此可以使用 Blob 的方法和属性。

File API 的出现,使得开发者能够在客户端对文件进行预处理,如验证文件类型、大小,甚至读取文件内容,从而提升用户体验并减轻服务器负担。

二、File 对象

(一)构造函数

File 对象可以通过构造函数创建,通常用于生成新的文件对象。构造函数的语法如下:

new File(array, name, [options]);
  • array:一个数组,包含文件的内容,可以是字符串或二进制数据。
  • name:文件名或路径。
  • options:可选参数,用于设置文件的 MIME 类型和最后修改时间。

例如,创建一个简单的文本文件:

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

(二)实例属性和方法

File 对象继承自 Blob,因此具有以下实例属性:

  • File.lastModified:文件最后修改的时间戳。
  • File.name:文件名。
  • File.size:文件大小,以字节为单位。
  • File.type:文件的 MIME 类型。

File 对象没有自己的实例方法,但可以使用 Blob 的方法,如 slice()

三、FileList 对象

FileList 对象是一个类数组对象,包含多个 File 对象。它通常出现在以下两个场景中:

  1. 文件上传控件(<input type="file">)的 files 属性。
  2. 拖拽文件时,DataTransfer.files 属性。

例如:

<input type="file" id="file" multiple>
const input = document.getElementById("file");
input.onchange = (event) => {
  const files = event.target.files; // FileList 对象
  console.log(files);
};

FileList 对象具有以下属性和方法:

  • length:返回 FileList 中的文件数量。
  • item(index):返回指定索引的 File 对象。

由于 FileList 是类数组对象,可以直接使用方括号访问文件,例如 files[0]

四、FileReader 对象

FileReader 对象用于异步读取文件内容。它提供了多种方法来读取文件,支持文本、二进制和 Data URL 格式。FileReader 的构造函数如下:

const reader = new FileReader();

(一)实例属性

FileReader 提供了以下实例属性:

  • FileReader.error:读取文件时产生的错误对象。
  • FileReader.readyState:读取文件时的当前状态(0:未加载,1:加载中,2:加载完成)。
  • FileReader.result:读取完成后的文件内容,可能是字符串或 ArrayBuffer。
  • FileReader.onabortonerroronloadonloadstartonloadendonprogress:事件监听函数,用于处理读取过程中的各种事件。

(二)实例方法

FileReader 提供了以下实例方法:

  • FileReader.abort():终止读取操作。
  • FileReader.readAsArrayBuffer(blob):以 ArrayBuffer 格式读取文件。
  • FileReader.readAsBinaryString(blob):以二进制字符串格式读取文件。
  • FileReader.readAsDataURL(blob):以 Data URL 格式读取文件。
  • FileReader.readAsText(blob, encoding):以文本格式读取文件。

例如,读取文本文件:

<input type="file" id="file">
const input = document.getElementById("file");
input.onchange = (event) => {
  const file = event.target.files[0];
  const reader = new FileReader();

  reader.onload = (event) => {
    console.log(event.target.result); // 文件内容
  };

  reader.readAsText(file);
};

五、综合实例:文件预览与上传

以下是一个综合实例,展示如何使用 File API 实现文件预览和上传功能。

(一)HTML

<label>
  <input type="file" id="file" multiple>
  <div class="uploadImg">
    <div class="cross"></div>
  </div>
</label>

(二)CSS

.uploadImg {
  width: 150px;
  height: 150px;
  border: 1px dashed skyblue;
  border-radius: 30px;
  position: relative;
  cursor: pointer;
}

.cross {
  width: 30px;
  height: 30px;
  position: absolute;
  left: calc(50% - 15px);
  top: calc(50% - 15px);
}

.cross::before {
  content: "";
  width: 30px;
  height: 2px;
  background-color: skyblue;
  position: absolute;
  top: calc(50% - 1px);
}

.cross::after {
  content: "";
  width: 30px;
  height: 2px;
  background-color: skyblue;
  position: absolute;
  left: calc(50% - 15px);
  top: calc(50% - 1px);
  transform: rotate(90deg);
}

input[type="file"] {
  display: none;
}

(三)JavaScript

const fileInput = document.getElementById("file");
const uploadImg = document.querySelector(".uploadImg");
const cross = document.querySelector(".cross");

fileInput.onchange = () => {
  const files = fileInput.files;
  const reader = new FileReader();

  if (files.length > 0) {
    reader.readAsDataURL(files[0]);
  }

  reader.onload = () => {
    uploadImg.style.background = `url(${reader.result}) center/cover no-repeat`;
    cross.style.opacity = 0;
  };
};

在这个示例中,用户选择文件后,文件内容将被读取并显示为背景图像,同时隐藏上传图标。

六、File System Access API:面向未来的文件操作

虽然 File API 提供了强大的文件读取功能,但它主要关注文件的读取,而不是文件的存储。为了满足离线存储的需求,W3C 推出了 File System Access API,它允许 Web 应用程序直接与本地文件系统交互,提供更完整的文件操作能力。

File System Access API 提供了以下功能:

  • 打开文件:允许用户选择本地文件并读取内容。
  • 保存文件:允许用户将文件保存到本地。
  • 编辑文件:允许用户在本地编辑文件。

目前,File System Access API 仍处于实验阶段,仅在 Chrome 浏览器中得到支持。