web前端

File和Blob

2020-03-27  本文已影响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))

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

上一篇下一篇

猜你喜欢

热点阅读