唠唠 File API

参考自JavaScript高级程序设计(第3版)

不能直接访问用户计算机中的文件,一直是Web应用开发中的一大障碍。很多年前,处理文件的唯一方式就是在表单中添加字段;

File API的宗旨是为Web开发人员提供一种安全的方式,以便在客户端访问用户计算机中的文件,并更好地对这些文件执行操作

File API在表单中的文件输入字段的基础上,又添加了一些直接访问文件信息的接口。HTML5在DOM中为文件输入元素添加了一个files集合。

在通过文件输入字段选择了一或多个文件时,files集合中将包含一组File对象,每个File对象对应着一个文件。每个File对象都有下列只读属性

  • name:本地系统中的文件名

  • sieze:文件的字节大小

  • type:字符串,文件的MIME类型

  • lastModifiedDate:字符串,文件上次被修改的时间;

inputFile.onchange = function(e) {
    var target = e.target;
    console.log(target.files);  // 上次的文件集合
}

FileReader类型

FileReader类型实现的是一种异步文件读取机制。

方法:

  • readAsText(file, encoding)

    • 以纯文本形式读取文件,将读取到的文本保存在result属性中。第二个参数用于指定编码类型,是可选的;

  • readAsDataURL(file)

    • 读取文件并将文件以数据URI形式保存在result属性中

      • 如果是图片,就是base64格式

  • readAsBinaryString(file)

    • 读取文件并将一个字符串保存在result属性中,字符串中的每个字符表示一字节

  • readAsArrayBuffer(file)

    • 读取文件并将一个包含文件内容的ArrayBuffer保存在result属性中。

  • abort()

    • 中断读取过程

最有用的三个事件:

  • progress

    • 读取过程中触发(每过固定的毫秒数就触发一次)

    • event对象中包含三个属性:lenthComputable、loaded和total;

  • erro 读取错误

  • load 读取成功

读取文件图片例子

inputFile.onchange = function (e) {
   var file = e.target.files[0]  // 拿到单独文件对象
   var reader = new FileReader()	// 创建读取文件实例


    reader.onprogress = function(e) {
       console.log(e.loaded / e.total)
    }
    reader.onerror = function(){
       console.log('文件读取失败')
    }
    reader.onload = function(){
       console.log('文件读取完成')
       img.src = reader.result
    }
    reader.readAsDataURL(file)	// 将文件以数据URI形式保存在result属性中
}

文件部分内容

inputFile.onchange = function (e) {   // 这里我是拿记事本做测试,为了方便看到字
    var file = e.target.files[0]
    var reader = new FileReader(), 
        blob = file.slice(0, 20)  // 读取指定字节,从0开始往后的20个字节
            
    reader.readAsText(blob)   // 此时读取的应该是blob实例
    reader.onload = function(){
         console.log('文件读取完成', reader.result)
    }
}

对象URL

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

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

要创建对象URL,可以使用URL.createObjectURL()方法,并传入File或Blob对象

inputFile.onchange = function(e) {
    var file = e.target.files[0]
    url = URL.createObjectURL(file)
    
    img.src = url
}

这个函数的返回值是一个以blob:开头的字符串,指向一块内存的地址。

因为这个字符串是URL,所有可以在页面中使用(一般用于图片的src指向);

如果不再需要相应数据,最好释放它占用的内存。但只要有代码在引用对象URL,内存就不会释放;

手动释放:URL.revokeObjectURL(url)

通过调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了

 

读取拖放的文件

拖动的文件信息保存在event.dataTransfer.files中

// 一定要取消这两个的默认行为
box.ondragenter = box.ondragover = function (e) {
    e.preventDefault()
}

box.ondrop = function (e) {
   var file = e.dataTransfer.files[0] 

   var reader = new FileReader()
   reader.readAsDataURL(file)
   reader.onload = function () {
       img.src = reader.result
   }

   e.preventDefault()
   // 这个是个小细节点,在火狐中,如果不取消冒泡,还是会冒到上级导致图片在新窗口打开
   e.stopPropagation() 
}

使用XHR上传拖放的文件

使用FormData类型就很容易做到,结果与通过表单上传一模一样。

// 一定要取消这两个的默认行为
box.ondragenter = box.ondragover = function (e) {
    e.preventDefault()
}


box.ondrop = function (e) {
    let file = e.dataTransfer.files[0], data = new FormData()

    data.append('dropFile', file)
    
    // 这里我用node写好了后台,上传成功后返回文件名,方便展示
    var xhr = new XMLHttpRequest()
    xhr.open('post', 'http://localhost:3000/upload');
    xhr.send(data);	// 直接发送即可
    xhr.onreadystatechange = function(){
        if((xhr.status >= 200 && xhr.status < 400) && xhr.readyState === 4) {
            console.log(xhr.responseText)
            img.src = ('http://localhost:3000/' + xhr.responseText)
        }
    }

    e.preventDefault()
    e.stopPropagation()
}

 

你可能感兴趣的:(Javascript)