JavaScript中 FileReader 对象详解
Posted 明天也要努力
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript中 FileReader 对象详解相关的知识,希望对你有一定的参考价值。
1. 简介
FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
其中 File 对象可以是来自用户在一个 < input > 元素上选择文件后返回的 FileList 对象,也可以来自拖放操作生成的 DataTransfer 对象,还可以是来自在一个 htmlCanvasElement 上执行 mozGetAsFile() 方法后返回结果。
重要提示: FileReader 仅用于以安全的方式从用户(远程)系统读取文件内容,不能用于从文件系统中按路径名简单地读取文件。 要在javascript中按路径名读取文件,应使用标准 Ajax 解决方案进行服务器端文件读取。如果读取跨域,则使用 CORS 权限。
属性
属性 | 描述 |
---|---|
FileReader.error | 一个DOMException,表示在读取文件时发生的错误 。 |
FileReader.result | 返回文件的内容。只有在读取操作完成后,此属性才有效,返回的数据的格式取决于是使用哪种读取方法来执行读取操作的。 |
FileReader.readyState | 表示FileReader状态的数字。 EMPTY 0 还没有加载任何数据。 LOADING 1 数据正在被加载。DONE 2 已完成全部的读取请求。 |
方法
FileReader 的实例拥有 4 个方法,其中 3 个用以读取文件,另一个用来中断读取。
下面的表格列出了这些方法以及他们的参数和功能,
需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result属性中。
方法名 | 描述 |
---|---|
FileReader.abort() | 中止读取操作。在返回时,readyState 属性为 DONE。 |
FileReader.readAsArrayBuffer() | 开始读取指定的 Blob 中的内容。 一旦完成,result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象。 |
FileReader.readAsBinaryString() | 开始读取指定的 Blob 中的内容。一旦完成,result 属性中将包含所读取文件的原始二进制数据。 |
FileReader.readAsDataURL() | 开始读取指定的 Blob 中的内容。一旦完成,result 属性中将包含一个 data: URL 格式的 Base64 字符串以表示所读取文件的内容。 |
FileReader.readAsText() | 开始读取指定的Blob中的内容。一旦完成,result 属性中将包含一个字符串以表示所读取的文件内容。 |
事件处理
FileReader 包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。
事件 | 描述 |
---|---|
FileReader.onabort | 处理 abort 事件。该事件在读取操作被中断时触发。 |
FileReader.onerror | 处理 error 事件。该事件在读取操作发生错误时触发。 |
FileReader.onload | 处理 load 事件。该事件在读取操作完成时触发。 |
FileReader.onloadstart | 处理 loadstart 事件。该事件在读取操作开始时触发。 |
FileReader.onloadend | 处理 loadend 事件。该事件在读取操作结束时(要么成功,要么失败)触发。 |
FileReader.onprogress | 处理 progress 事件。该事件在读取Blob时触发。 |
因为 FileReader 继承自 EventTarget,所以所有这些事件也可以通过 addEventListener 方法使用。
检测浏览器对 FileReader 的支持
if(window.FileReader) {
var fr = new FileReader();
// add your code here
}else {
alert("Not supported by your browser!");
}
2. FileReader 对象的使用
2.1 基本使用
准备文件
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="format-detection" content="telephone=no">
<title>test</title>
</head>
<body>
<div>
<input type="file">
<input type="file" id="imgFile">
<img src="" id="preview">
</div>
<script type="text/javascript">
let inputFile = document.querySelector('input[type=file]');
inputFile.onchange = function(){
var reader = new FileReader()
// result 属性中将包含一个字符串以表示所读取的文件内容。
reader.readAsText(this.files[0])
reader.onload = function(){
console.log(this.result)
}
}
let imgFile = document.querySelector('#imgFile');
let priview = document.querySelector("#preview");
imgFile.onchange = function () {
var reader = new FileReader();
// result 属性中将包含一个 data: URL 格式的 Base64 字符串以表示所读取文件的内容
reader.readAsDataURL(this.files[0])
reader.onload = function () {
priview.src = reader.result;
console.log(this.result)
}
}
</script>
</body>
</html>
效果:
2.2 事件处理
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="format-detection" content="telephone=no">
<title>test</title>
</head>
<body>
<div>
<input type="file">
</div>
<script type="text/javascript">
let inputFile = document.querySelector('input[type=file]');
inputFile.onchange = function(){
var reader = new FileReader()
// result 属性中将包含一个字符串以表示所读取的文件内容。
reader.readAsText(this.files[0])
reader.onloadstart = function(){
console.log("onloadstart状态"+this.readyState)
}
reader.onloadend= function(){
console.log("onloadend状态"+this.readyState)
}
reader.onprogress = function(){
console.log("onprogress状态"+this.readyState)
}
reader.onload = function(){
console.log("onload状态"+this.readyState,"获取的数据:"+this.result);
}
reader.onerror = function(){
console.log('出错了')
}
reader.onerror = function(){
console.log('处理abort事件。该事件在读取操作被中断时触发。')
}
}
</script>
</body>
</html>
效果:
分析:
- onloadstart 状态:数据正在被加载;
- onloadend 状态:已完成全部的读取请求;
- .当然状态为 0(readyState)表示还没有加载任何数据;
- 每过50ms左右,就会触发一次 progress 事件;也就是说这个可能多次触发,onload 事件在 onloadend 之前触发;
- 由于种种原因无法读取文件时,会触发 error 事件。触发 error 事件时,相关信息保存在 FileReader 对象的 error 属性中,这个属性将保存一个对象,此对象只有一个属性 code,即错误码。1 表示未找到文件,2 表示安全性错误,3 表示读取中断,4 表示文件不可读,5 表示编码错误;
- 如果想中断读取过程,可调用 abort 方法,就会触发 abort 事件。在返回时,readyState 属性为 DONE。一般用于后台的操作;
2.3 node操作文件
根据以上可知,浏览器中的 JavaScript 是没有文件操作的能力的(基于安全,不能直接操作本地文件),但是 Node 中的 JavaScript 具有文件操作的能力。
读取文件
// 1. 使用 require 方法加载 fs 核心模块
var fs = require('fs')
// 2. 读取文件
// 第一个参数就是要读取的文件路径
// 第二个参数是一个回调函数
// 成功
// data 数据
// error null
// 失败
// data undefined没有数据
// error 错误对象
fs.readFile('read.txt', function (error, data) {
// 在这里就可以通过判断 error 来确认是否有错误发生
if (error) {
console.log('读取文件失败了')
} else {
console.log(data.toString())
}
})
文件读取是异步操作
当我们读取多个文件,发现使用 readfile 读取文件并不能一定按顺序打印结果,所以这是一个异步操作,如何顺序读取文件。
使用 Promise
var fs = require('fs')
function pReadFile(filePath) {
return new Promise(function (resolve, reject) {
fs.readFile(filePath, 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
pReadFile('./data/a.txt')
.then(function (data) {
console.log(data)
return pReadFile('./data/b.txt')
})
.then(function (data) {
console.log(data)
return pReadFile('./data/c.txt')
})
.then(function (data) {
console.log(data)
})
文件写入
fs.writeFile('read.txt', '大家好,给大家介绍一下,我是文件写入', function (error) {
if (error) {
console.log('写入失败')
} else {
console.log('写入成功了')
}
})
以上是关于JavaScript中 FileReader 对象详解的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript 中的FileReader对象(实现上传图片预览)
3分钟上手JS中的FileReader对象(实现上传图片预览)
HTML5 File API:在 FileReader 回调中获取 File 对象
JavaScript 之 FileReader简介以及原生uniapp如何将文件转成base64编码字符串示例