重学JS | 玩转File API

这是我参与更文挑战的第18天,活动详情查看:更文挑战

[重学JavaScript系列文章连载中…]

读取文件,我们刚开始接触的是通过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是一种异步文件读取机制。

它有如下方法:

  1. readAsText(file,encoding):以纯文本的形式读取文件
  2. readAsDataURL(file):读取文件并将文件以数据URI的格式保存到result
  3. readAsBinaryString(file):读取文件并将一个字符串保存在result属性中,字符串中的每个字符表示一字节
  4. readAsArrayBuffer(file):读取文件并将一个包含文件内容的ArrayBuffer保存到result属性中

它有如下事件:

  1. progress:表示又读取了数据,50ms左右触发一次
  2. error:发生了错误触发
  3. load:已经读完了整个文件触发
  4. abort:中断读取过程
  5. 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='https://juejin.cn/post/${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="https://juejin.cn/post/${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相关知识。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享