前端必知必会之文件读取、拖拽上传

在前端开发中,拖拽上传文件是一种很常见的需求。经过拖拽来实现文件上传须要了解FileReader这个File API以及对应的拖拽事件前端

咱们先了解一下,在前端表单中是如何处理文件上传的浏览器

files集合

一直以来,咱们都经过<input type='file'>字段来获取文件的对应信息。HTML5为文件输入元素添加了一个files集合,在files集合中,有一组File对象,每一个File对象对应着一个文件bash

File对象属性(只读属性):服务器

属性 类型 描述
name 字符串 本地文件系统中的文件名
size 数字 文件的字节大小
type 字符串 文件的MIME类型
lastModifiedDate 字符串 文件上一次被修改的时间

具体的实现代码以下:app

<input type='file' id='files'>
<script>
    var files = document.getElementById('files')
    files.addEventListener('change', function(event) {
        console.log(event.target.files)
        console.log(
            `文件名称:${event.target.files[0].name}
             文件类型:${event.target.files[0].type}
             文件大小:${event.target.files[0].size} bytes`
             )
    })
</script>
复制代码

实例结果截图:异步

files集合只能知道一些文件的基本信息,FileReader类型才是File API的重头戏post

FileReader类型

FileReader类型实现是一种异步文件读取机制,读取的是文件系统。能够经过如下方法读取文件中的内容ui

方法名 参数 输出内容 描述
readAsText file,encoding 纯文本 异步以纯文本形式读取文件,将读取到的文本保存在result属性中
readAsDataURL file DataURI的形式 异步读取文件并将文本以数据URI的形式保存在result属性中
readAsBinaryString file 二进制 异步读取文件内容并将包含文件内容的二进制字符串保存在result属性中
readAsArrayBuffer file ArrayBuffer 异步读取文件并将一个包含文件内容的ArrayBuffer保存在result属性中
abort -- -- 用于中断文件读取过程

具体文件输出代码:url

<input type='file' id='files'>
<script>
    var files = document.getElementById('files')
    files.addEventListener('change', function (event) {
        let file = event.target.files[0]
        let reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = function () {
            console.log(reader.result)
        }
    })
</script>
复制代码

咱们以上传图片,输出DataURL为例spa

其余三种不一样的文件输出,只需将上述reader.readAsDataURL(file)的代码替换方法便可,因为篇幅有限,就不在此展开,读者能够建立对应的文件一一尝试

由于文件读取过程是异步的,FileReader也提供了几个对应的事件,同时在上述的代码中,咱们也已经使用了FileReader中的load事件来判断是否已经读完整个文件

事件名称 事件描述
onabort 读取被终止时调用
onerror 读取出错时调用
onload 读取成功时调用
onloadend 读取完成时调用,无论是读取成功仍是失败
onloadstart 读取将要开始时出发
onprogress 读取过程当中周期性触发,每50ms左右触发一次,能够用来监听文件读取的进度

读取部份内容

有时候,咱们只想读取文件的一部分而不是所有内容。为此,File对象还支持了一个slice()方法,slice()方法接受两个参数:起始字节数以及要读取的字节数。这个方法返回一个Blob实例,Blob是File类型的父类型

咱们新建一个从1到10的txt,读取1-5的内容

输出结果:

如下就是读取文件部份内容的代码

<input type='file' id='files'>
<script>
    var files = document.getElementById('files')
    files.addEventListener('change', function (event) {
        let file = event.target.files[0]
        let reader = new FileReader()
        blob = file.slice(0, 10)
        reader.readAsText(blob)
        reader.onload = function () {
            console.log(reader.result)
        }
    })
</script>
复制代码

对象URL

有时候咱们想要上传图片以后,直接在网页中展现出来,这时候,咱们就可使用对象URL

对象URL也被称为blob URL,指的是引用保存在FileBlob中数据的URL,要建立对象URL,可使用window.URL.createObjcetURL()方法,并传入FileBlob对象,方法就会返回一个字符串,指向一块内存地址。那么咱们就能够动态将字符串URL插入img标签中,从而实现网页上传图片展现了

具体代码以下:

<input type='file' id='files'>
<div id='images'></div>
<script>
    var files = document.getElementById('files')
    var images = document.getElementById('images')
    files.addEventListener('change', function (event) {
        let file = event.target.files[0]
        url = window.URL.createObjectURL(file)
        if (url) {
            images.innerHTML = `<img width='300' height='300' src=${url} />`
        }
    })
</script>
复制代码

若是已经不须要了相对应的对象URL数据,最好释放它占用的内容。咱们能够经过将对象URL传给window.URL.revokeObjectURL(),那么就能手工释放其占用的内存

读取拖拽文件

咱们能够结合HTML5拖拽API文件API,来实现从桌面把文件拖放到对应网页的目标上。从桌面上把文件拖放到浏览器中会触发drop事件,从而就能经过event.dataTransfer.files读取到拖拽文件的信息

当文件拖拽网页位置上以后能获取到文件的信息:

具体代码以下:

<div id='droptarget' style="width: 200px; height: 200px; border:1px solid black"></div>
<script>
    var droptarget = document.getElementById('droptarget')
    droptarget.addEventListener('drop', function (event) {
        event.preventDefault(); //禁止浏览器默认行为,浏览器默认会直接打开显示
        if (event.type === 'drop') {
            //获取文件信息,同File对象相同
            var files = event.dataTransfer.files;
            console.log(
                `文件名称:${files[0].name},文件类型:${files[0].type},文件大小:${files[0].size} bytes`
            )
        }
    })
    droptarget.addEventListener('dragenter', function (event) {
        //禁止浏览器默认行为,浏览器默认会直接打开显示
        event.preventDefault();
    })
    droptarget.addEventListener('dragover', function (event) {
        //禁止浏览器默认行为,浏览器默认会直接打开显示
        event.preventDefault();
    })
</script>
复制代码

使用XHR文件上传

咱们已经能够经过File API来访问到文件中的内容,那么咱们就能够利用这一点来经过XHR实现文件的上传。咱们能够经过FormData以表单的方式来上传文件内容。首先咱们建立一个FormData对象,经过调用append()方法并传入相应的File对象做为参数,再经过XHRsend()方法,就能够将文件内容上传到服务器端。

具体的代码根据上面的读取拖拽文件代码进行改造,从而实现拖拽文件上传:

droptarget.addEventListener('drop', function (event) {
    event.preventDefault();
    if (event.type === 'drop') {
        var data = new FormData();
        var files = event.dataTransfer.files;
        data.append("file", files[0]) //若是有多个文件上传,可对应遍历files对象加入到data中
        var xhr = new XMLHttpRequest();
        xhr.open('post', url, true); //url表示文件上传服务器的地址
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                console.log(xhr.responseText)
            }
        }
    }
    xhr.send(data);
})
复制代码

最后

若是以为文章对你有帮助,请帮忙多多点赞,动动小手,你的点赞是我写做最大的动力

相关文章
相关标签/搜索