读取文件,我们刚开始接触的是通过 input 标签,实现起来像这样:
<body>
<input type='file' onchange="fileChange(this)"/>
<script>
function fileChange(target){
// 得到第一个上传的文件对象
var file = target.files[0]
var fileInfo = '文件名:'+file.name+'类型:'+file.type+'文件字节大小:'+file.size+'上次修改时间:'+file.lastModifiedDate
console.log(fileInfo)
}
</script>
</body>
复制代码
现如今 File API 提供了一种更安全访问客户端文件的方式,甚至可以通过 FileReader 读取文件中的数据。
FileReader
FileReader 是一种异步文件读取机制。
它有如下方法:
readAsText(file,encoding):以纯文本的形式读取文件
readAsDataURL(file):读取文件并将文件以数据 URI 的格式保存到 result
readAsBinaryString(file):读取文件并将一个字符串保存在 result 属性中,字符串中的每个字符表示一字节
readAsArrayBuffer(file):读取文件并将一个包含文件内容的 ArrayBuffer 保存到 result 属性中
它有如下事件:
progress:表示又读取了数据,50ms 左右触发一次
error:发生了错误触发
load:已经读完了整个文件触发
abort:中断读取过程
loadend:整个过程结束,load、error、abort 事件触发后触发的事件
看个例子:
<body>
<input type='file' onchange="fileChange(this)"/>
<div id='output' />
<script>
function fileChange(target){
// 得到第一个上传的文件对象
var file = target.files[0],
output = document.getElementById('output'),
type = '',
reader = new FileReader();
if(/image/.test(file.type)){
type = 'image'
reader.readerAsDataURL(file)
}else{
type = 'text'
reader.readAsText(file)
}
// 文件读取进度
reader.onprogress = function(e){
if(e.lengthComputable){
console.log('当前读取进度为':e.loaded+'/'+e.total)
}
}
// 文件读取错误
reader.onerror = function(){
// 1: 未找到文件 2:安全性错误 3:读取中断 4:文件不可读 5:编码错误
var errCode = reader.error.code
}
// 文件读取完成
reader.onload = function(){
// reader.result: 读取的文件
var html = type==='image'?`<img src='${reader.result}'>`:reader.result
output.innerHtml = html
}
// 整个流程结束
reader.onloadend = function(){}
}
</script>
</body>
复制代码
读取部分文件
File 对象支持一个 slice()方法,接收两个参数:起始字节及要读取的字节数。返回一个 Blob 的实例,Blob 是 File 类型的父类型。
示例伪代码:
// 截取内容不同浏览器上的兼容方法
function blobSlice(blob,start,length){
if(blob.slice){
return blob.slice(start,length)
}else if(blob.webkitSlice){
return blob.webkitSlice(start,length)
}else if(blob.mozSlice){
return blob.mozSlice(start,length)
}else{
return null
}
}
// 伪代码,只展示核心
var reader = new FileReader()
var file = target.files[0]
// 读取32字节内容
var blob = blobSlice(file,0,32)
reader.readAsText(blob)
复制代码
对象 URL
对象 URL 也被称为 blob URL,指的是引用保存在 File 或 Blob 中数据的 URL。好处是不必把文件内容读取到 JavaScript 中而直接使用文件内容。当然没使用的时候要释放 URL 占用的空间。
示例伪代码如下:
// 创建URL对象
function createObjectUrl(blob){
if(window.URL){
return window.URL.createObjectURL(blob)
}else if(window.webkitURL){
return window.webkitURL.createObjectURL(blob)
}else{
return
}
}
// 销毁URL对象
function revokeObjectURL(url){
if(window.URL){
window.URL.revokeObjectURL(url)
}else if(window.webkitURL){
window.webkitURL.revokeObjectURL(url)
}
}
// 假设为图片文件对象
var file = target.files[0]
// 创建图片URL对象
var url = createObjectUrl(file)
var html = `<img src="${url}"/>`
// 销毁URL对象
revokeObjectURL(url)
复制代码
拖拽文件上传
结合 H5 拖放 API 和文件 API,能够创造出令人瞩目的用户界面。这里基本流程代码:
var oBox = document.getElementById('box');
var oM = document.getElementById('m1');
var timer = null;
document.ondragover = function(){
console.log('文件来了')
};
//进入子集的时候 会触发ondragover 频繁触发 不给ondrop机会
oBox.ondragenter = function(){
oBox.innerHTML = '请释放鼠标';
};
oBox.ondragover = function(){
return false;
};
oBox.ondragleave = function(){
oBox.innerHTML = '请将文件拖拽到此区域';
};
oBox.ondrop = function(ev){
var file = ev.dataTransfer.files[0];
var reader = new FileReader();
//读取成功
reader.onload = function(){
console.log(reader);
// 此处进行文件上传
var form = new FormData()
form.append('file',file)
... // 其他代码略
};
reader.onloadstart = function(){
console.log('读取开始');
};
reader.onloadend = function(){
console.log('读取结束');
};
reader.onabort = function(){
console.log('中断');
};
reader.onerror = function(){
console.log('读取失败');
};
reader.onprogress = function(e){
console.log('当前读取进度为':e.loaded+'/'+e.total)
};
};
复制代码
总结
至此我们学了 File API 相关知识。
评论