File API

发表于: 2015-08-23分类于:JavaScript

File API

将input的type 设置为file 之后,点击可以选择本地文件,然后在这个的input元素中为文件输入元素添加了一个 files 集合,可以在这个集合中读取文件的name,type 以及大小。

FileReader 类型

为了获得文件的内容,就需要用来 FileReader 这个类,它与 XMLHttpRequest 对象有些相似,都是异步读取数据,不同的是 FileReader 读取的是本地文件。

可以使用下面几个方法开始读取一个文件:

  • readAsText(file,encoding) :以纯文本形式读取文件,将读取到的文本保存在 result 属性中。第二个参数用于指定编码类型,是可选的。
  • readAsDataURL(file) :读取文件并将文件以数据 URI 的形式保存在 result 属性中。
  • readAsBinaryString(file) :读取文件并将一个字符串保存在 result 属性中,字符串中的每个字符表示一字节。
  • readAsArrayBuffer(file) : 读取 文 件 并将 一 个 包 含文 件 内 容 的 ArrayBuffer 保 存在result 属性中。

之后可以在 FileReader 对象上面监听下面几种事件,然后在合适的时机进行处理:

  • progress
  • error
  • load
  • abort
  • loadend

事件的作用,顾名思义。

progress

在读取文件的时候每过 50ms 左右,就会触发一次 progress 事件,通过事件对象可以获得与 XHR 的 progress 事件相同的信息(属性): lengthComputable 、 loaded 和 total 。lengthComputable 指示文件长度是否可以计算。

error

由于种种原因无法读取文件,就会触发 error 事件。触发 error 事件时,相关的信息将保存到FileReader 的 error 属性中。这个属性中将保存一个对象,该对象只有一个属性 code ,即错误码。这个错误码是 1 表示未找到文件,是 2 表示安全性错误,是 3 表示读取中断,是 4 表示文件不可读,是5 表示编码错误。

load

文件成功加载后会触发 load 事件;如果发生了 error 事件,就不会发生 load 事件。

abort

在读取过程中调用abort 方法可以中断读取,而这就会触发 abort 事件

loadend

在触发 load 、 error 或 abort 事件后,会触发另一个事件 loadend 。 loadend 事件发生就意味着已经读取完整个文件,或者读取时发生了错误,或者读取过程被中断。

读取部分内容

有时候可能只是希望读取部分文件内容,那么这个时候就可以使用 File 对象的 slice 方法。这个方法返回一个 Blob 的实例, Blob 是 File 类型的父类型

file.slice(startByte, length);

Blob 类型有一个 size 属性和一个 type 属性,而且它也支持 slice() 方法.

对象URL

对象 URL 也被称为 blob URL,指的是引用保存在 File 或 Blob 中数据的 URL。使用对象 URL 的好处是可以不必把文件内容读取到 JavaScript 中而直接使用文件内容。为此,只要在需要文件内容的地方提供对象 URL 即可。要创建对象 URL,可以使用 window.URL.createObjectURL() 方法,并传入File 或 Blob 对象。

url =  window.URL.createObjectURL(files[0]);
output.innerHTML = "<img src=\"" + url + "\">";

如果不再需要相应的数据,最好释放它占用的内容。但只要有代码在引用对象 URL,内存就不会释放。要手工释放内存,可以把对象 URL 传给 window.URL.revokeOjbectURL()

读取拖放的文件

从桌面上把文件拖放到浏览器中也会触发 drop 事件。而且可以在 event.dataTransfer. files中读取到被放置的文件,当然此时它是一个 File 对象,与通过文件输入字段取得的 File 对象一样。这样就可以用 FileReader 对象来读取文件了。

使用XHR上传文件

读取到了本地文件,然后将文件内容使用 ajax 的 send方法 使用post方式发送到服务器就完成了文件上传。但是更加有效率的方法是使用FormData对象

data = new FormData();
data.append("file", files[0]);
xhr.send(data);