HTML5 FileReader 文件操作

2,038 阅读3分钟

本文是关于 HTML5 FileReader 文件操作的学习笔记,这里做个总结与分享,有不足之处还望斧正~

FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件,支持读取 File 或 Blob 对象指定要读取的文件或数据。

获取文件

File 对象来源

  • 用户在一个 <input> 元素上选择文件后返回的 FileList 对象
<!-- getInfo() 传入 this 获取的是 input 节点 -->
<input type="file" onchange="getInfo(this)">
<script type="text/javascript">
  function getInfo(node) {
    console.log(node)
  }
</script>

打印 node,输出的是 input 节点:

image.png

类型为 "file" 元素拥有 files 属性,那么我们 console.log(node.files) 可得到一个 FileList 对象:

image (1).png

这样我们就可以通过 node.files[0] 得到 File 对象。

注:如果给 input 添加 multiple 属性,就可以选择多个文件,FileList 对象就会有多个子元素,
比如:<input type="file" multiple onchange="getInfo(this)">,选择 2 张图片,打印 node.files 可得:

image (2).png

  • 来自拖放操作生成的 DataTransfer 对象

获取文件信息

FileReader() 读取文件

创建一个 FileReader 对象 const fr = new FileReader()

FileReader 介绍

常用方法

  • abort():终止该读取操作;
  • readAsDataURL():开始读取,读取完成后,result 属性中将包含一个 data: URL 格式的 Base64 字符串以表示所读取文件的内容;
  • readAsText():开始读取,读取完成后,result 属性中将包含一个字符串以表示所读取文件的内容。

属性

本文只介绍将用到的 3 个属性:

  1. result:读取到的文件内容 (只读属性);
  2. onload:读取操作成功完成时调用 (事件处理);
  3. onerror:读取操作发生错误时调用(事件处理)。

读取文件代码

<input type="file" multiple onchange="getInfo(this)">
<script type="text/javascript">
  function getInfo(node) {
    const fileObj = node.files[0]
    
    // 创建 FileReader 对象
    const fr = new FileReader()
    
    // 监听读取成功(监听函数写在读取前面保证监听成功)
    fr.onload = (e) => {
      const result = e.target.result
      console.log(result)
    }
    
    // 读取文件
    fr.readAsDataURL(fileObj)
    // fr.readAsText(fileObj)
  }
</script>

打印得到一个 base64 字符串:

image (3).png
注意:通过 base64 字符串能得到的也可以是文本,比如选择一文件,内容为 123,则得到的结果将是 data:text/plain;base64,MTIz 在浏览器输入后,页面将显示 123。

如果要直接获取文字内容,则可以将 fr.readAsDataURL(fileObj) 换成 fr.readAsText(fileObj),则输出的结果直接是文本内容。

展示文件内容

先获取到文件,然后转成 base64 地址字符串,最后再添加到 dom 树中即可。

注:因为 FileReader 是异步读取文件内容的,所以用 Promise 处理了下,这样即使是同时选择多张图片也可以正常执行:

<input type="file" multiple onchange="handleChange()">
<div id="content">
</div>
<script type="text/javascript">
  const input = document.querySelector('input')
  function handleChange() {
    // 获取图片文件
    const imgFileList = input.files
    
    for (let item of imgFileList) {
      // 读取图片转出地址,并添加到 dom 树中
      fileToBase64(item).then(res => {
        content.innerHTML += `<img src="${res}" style="width: 30%">` // dom 元素可以直接使用 id 名称来获取
      }).catch(reason => {
        console.log(reason)
      })
    } 
  }
  
  function fileToBase64(file) {
    return new Promise((resolve, reject) => {
      const fr = new FileReader()
      // 监听
      fr.onload = e => {
        resolve(e.target.result)
      }
      // 读取
      fr.readAsDataURL(file)
      fr.onerror = () => {
        reject(new Error('读取错误'))
      }
    })
  }
</script>

One More Thing

获取到 File 对象后,用 URL.createObjectURL() 也可以得到一个 url 用于展示,例如:blob:http://127.0.0.1:8848/15609d4d-362e-4528-a9ce-f07fe684ceed, 但这只是一个文件地址,使用 FileReader 获得的是 base64 编码,表示的是整张图片。
感谢.gif

点赞.png