File和Blob

作者: 姜治宇 | 来源:发表于2020-03-27 17:42 被阅读0次

    Blob,英文是binary large object,就是大的二进制对象,File接口基于Blob, 继承了Blob的功能,可以把File当成Blob的子类。
    前端在处理图片、音频等二进制数据时,不可避免的要跟这俩哥们打交道。
    以图片上传为例,我们需要弄清楚这么几件事:

    一、如何捕获文件?

    要实现图片上传,首先要本地选择一张图片,然后拿到它。怎么做到呢?
    1、html标签必须标明是file类型。

     <input type="file" id="hello" />
    

    2、通过onchange事件获取File对象。

    var hello = document.getElementById('hello')
        hello.onchange = function(e){
            var files = e.target.files//得到的是FileList对象
            console.log(files[0])//得到File
        }
    
    File对象的主要属性有:name(文件名)、size(大小)、type(类型)等。 file.jpg
    二、如何读取文件?

    File对象拿到了,目前看到只有一些属性信息。那如何读取到这张图片呢?
    浏览器提供了一个叫FileReader的对象来帮我们实现。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>file</title>
    </head>
    <body>
        <div>
            <input type="file" id="hello" />
        </div>
    
        <div id="readPic"></div>
    </body>
    </html>
    <script>
        var hello = document.getElementById('hello')
        hello.onchange = function(e){
            var files = e.target.files//得到的是FileList对象
    
            var fr = new FileReader()
            fr.readAsDataURL(files[0])
            fr.onload = function(){
                document.getElementById('readPic').innerHTML = '<img src=\"' + fr.result +'\">';
            }
        }
    </script>
    

    FileReader类主要有这么几个方法:
    1)readAsText(file, encoding)
    以纯文本形式读取文件,读取到的文本保存在result属性中。第二个参数代表编码格式。
    2)readAsDataUrl(file)
    读取文件并且将文件以数据URI的形式保存在result属性中。
    3)readAsBinaryString(file)
    读取文件并且把文件以字符串保存在result属性中。
    4)readAsArrayBuffer(file)
    读取文件并且将一个包含文件内容的ArrayBuffer保存咋result属性中。
    因为文件读取的过程是异步的,因此还提供了三个监听事件:
    1)progress事件
    监听进度事件,每隔50ms左右会触发一次。
    2)error事件
    监听错误事件,在无法读取到文件信息的条件下触发。
    3)load事件
    监听成功事件,在文件成功加载后就会触发。

    三、如何上传文件?

    图片拿到了,也能本地预览了,下面就是要上传了。在网路传输数据前,一般都需要先进行表单serialize序列化
    什么是序列化呢?这个很容易理解,比如有这么一个表单:

    <form action="xxx">
            <input type="text" name="user" />
            <input type="password" name="pw" />
            <input type="submit" value="提交" />
    </form>
    

    当你点击提交后,表单参数就会以字符串的方式传到后台:

    user=zhangsan&pw=123456
    

    这样后台就可以通过get或post方法提取到数据了。
    但是二进制数据比较特殊,我们不可能跟字符串一样的方式传输,怎么办呢?
    浏览器提供了FormData对象帮我们来实现。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>file</title>
    </head>
    <body>
        <div>
            <input type="file" id="hello" />
        </div>
    
        <div id="readPic">显示图片</div>
        <div id="result">上传结果</div>
    </body>
    </html>
    <script>
        var hello = document.getElementById('hello')
        hello.onchange = function(e){
            var files = e.target.files//得到的是FileList对象
            //读取文件
            var fr = new FileReader()
            fr.readAsDataURL(files[0])
            fr.onload = function(){
                document.getElementById('readPic').innerHTML = '<img src=\"' + fr.result +'\">';
            }
            //上传文件
            var fd = new FormData()
            fd.append('file',files[0])
            var xhr = new XMLHttpRequest()
            xhr.open('post','/upload',true)
            xhr.onload = function () {
                if(this.status == 200 || this.status == 304){
                    document.querySelector("#result").innerText = this.responseText;
                }
            }
            xhr.send(fd)
        }
    </script>
    
    四、如何切割文件?

    遇到比较大的二进制文件时,比如一部几个g的电影,我们需要将大文件切割分片上传。如何切割文件呢?
    File对象提供了slice方法来帮我们实现。

    fd.append('file',files[0].slice(start,end))
    

    有了这些知识就可以捣鼓断点续传的功能了,我们下次再说。

    相关文章

      网友评论

        本文标题:File和Blob

        本文链接:https://www.haomeiwen.com/subject/razluhtx.html