FileReader API

2024-02-16  本文已影响0人  涅槃快乐是金

无需后端服务器,异步读取和解释上传的文件。
网站是如何在不存储任何数据的情况下解释上传的文件的吗?FileReader API就是答案!它允许客户端应用程序异步读取和解释上传的文件。

要在您自己的客户端应用程序中执行此操作,您还需要了解File APIBlob API。这些是您将使用FileReader API读取的对象。您还可以使用FileReader API来分析从拖放操作中获取的文件。

注意:这与较新的File System API不同,后者提供了浏览器(和客户端JavaScript)访问本地文件系统的功能。

尽管这个API已经存在一段时间了(Chrome在版本6中开始支持它),但现代用法的部分支持时间并不长,例如File API(在Chrome 13中发布)和File()构造函数(在Chrome 38中发布)。

基础知识

FileReader API在基本用法中,可以与<input type="file" />结合使用。一旦通过文件浏览器选择了文件,或者将文件拖放到文件字段上,就会在输入元素上创建一个新的File对象。

FileReader可以与任何File对象一起使用,但我们将探讨一个基本的用法场景。

让我们尝试将File对象传递给FileReader API,如下所示:

function readFile(file) {
    const fileReader = new FileReader();
    fileReader.readAsText(file);
}

然而,上面的示例还不够完整。FileReader API默认是异步的,并且不使用Promises。相反,您可以监听几个事件。

现在,让我们专注于以下事件:

function readFile() {
    const fileReader = new FileReader();
    const resultContainer = document.getElementById('result');
    const file = document.getElementById('uploaded-file').files[0];

    if (file) {
        fileReader.readAsText(file);
    }
    
    fileReader.addEventListener('load', () => {
        resultContainer.innerText = fileReader.result
    }, { once: true });
}

请注意,在上面的示例中,我们将resultContainer的文本设置为FileReader触发load事件后所获得的结果。

fileReader对象上的result属性正是您所期望的:FileReader从文件中读取的内容包含在result属性中。

虽然它无法读取每种类型文件的内容,但FileReader提供了以下方法:

方法:readAsText()

首先是FileReader API提供的非常基础的文本方法。您应该只在较小的文件上使用此方法,因为它会将整个文件读入内存。对于较大的文件,您应该使用readAsArrayBuffer(),因为它返回一个Promise,并且对于较大的文件更加可预测。

在上面的示例中,我们将传递给readFile()的文件并记录readAsText方法的结果。如果我们想读取任何类型的基于文本的文件,例如 .txt.csv等,这将非常有用。

<label>
  Upload file
  <input type="file" id="testfile" accept=".txt" onchange="readFile()">
</label>
<br> <br>
<div>
  Contents of Text File:
  <div id="result"></div>
</div>
function readFile() {
  const fileReader = new FileReader();
  const resultContainer = document.getElementById("result");
  const file = document.querySelector("input[type=file]").files[0];

  if (file) {
    fileReader.readAsText(file); // Read the file so fileReader.result is populated.
  }

  fileReader.addEventListener(
    "load",
    () => {
      resultContainer.textContent = fileReader.result;
    },
    { once: true }
  );
}

方法:readAsDataURL()

此方法可用于读取图像,类似于如果它们是数据URL字符串时与图像进行交互的方式。这正是此方法的作用:将图像作为base64编码的数据URL返回。

注意:它是readAsDataURL - URL中所有字母都大写 - 而不是readAsDataUrl。使用后者会导致错误 - 它是区分大小写的。

让我们看下面的示例:

<!-- 不要忘记以语义化方式编写HTML! -->
<label>
    <input type="file" id="uploaded-file" onchange="readImage()" name="uploaded-file" accept="image/*">
    上传一张图片。
</label>
<div id="result"></div>

请注意,我使用accept属性将上传的文件限制为图像类型的MIME类型。查阅MDN上有关如何指定要接受的文件类型的信息。

function readImage() {
    const fileReader = new FileReader();
    const file = document.getElementById("uploaded-file").files[0];
    
    if (file) {
        fileReader.readAsDataUrl(file);
    }

    fileReader.addEventListener('load', () => {
        const result = fileReader.result;
        const resultContainer = document.getElementById("result");
        const img = document.createElement("img");
        img.src = result;
        resultContainer.append(img);
    }, { once: true })
}

在上面的示例中,我们:

<label>
  Upload file
  <input type="file" id="testfile" accept="image/*" onchange="readImage()">
</label>
<br> <br>
<div>
  Image that was uploaded:
  <div id="result"></div>
</div>
function readImage() {
  const fileReader = new FileReader();
  const file = document.querySelector("input[type=file]").files[0];

  if (file) {
    fileReader.readAsDataURL(file);
  }

  fileReader.addEventListener(
    "load",
    () => {
      const result = fileReader.result;
      const resultContainer = document.getElementById("result");
      const img = document.createElement("img");
      img.src = result;
      resultContainer.append(img);
    },
    { once: true }
  );
}

此API非常适用于简单的浏览器操作,甚至可以用于上传图像/文本/文件到后端服务器时的实时状态更新。要在主要社交网络上更新个人资料图片?您可以使用FileReader API来复制此操作。

FileReader事件

FileReader上还有几个其他事件值得了解。

这些事件是从ProgressEvent接口扩展的。通过监听FileReader上的progress事件,您可以通过将ProgressEvent上的loaded除以total属性来计算文件读取进度。

fileReader.addEventListener("progress", (event) => {
  const progress = (event.loaded / event.total) * 100;
  console.log(`读取进度:${progress}%`);
});

进阶

FileReader是一个很棒的API,可用于许多客户端应用程序。它是许多您可能已经使用的应用程序的基础。

上一篇 下一篇

猜你喜欢

热点阅读