本文是关于 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 节点:
类型为 "file" 元素拥有 files
属性,那么我们 console.log(node.files)
可得到一个 FileList 对象:
这样我们就可以通过 node.files[0]
得到 File 对象。
注:如果给 input 添加 multiple 属性,就可以选择多个文件,FileList 对象就会有多个子元素,
比如:<input type="file" multiple onchange="getInfo(this)">
,选择 2 张图片,打印 node.files 可得:
- 来自拖放操作生成的 DataTransfer 对象
获取文件信息
FileReader() 读取文件
创建一个 FileReader 对象 const fr = new FileReader()
FileReader 介绍
常用方法
- abort():终止该读取操作;
- readAsDataURL():开始读取,读取完成后,result 属性中将包含一个 data: URL 格式的 Base64 字符串以表示所读取文件的内容;
- readAsText():开始读取,读取完成后,result 属性中将包含一个字符串以表示所读取文件的内容。
属性
本文只介绍将用到的 3 个属性:
- result:读取到的文件内容 (只读属性);
- onload:读取操作成功完成时调用 (事件处理);
- 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 字符串:
注意:通过 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 编码,表示的是整张图片。