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))
有了这些知识就可以捣鼓断点续传的功能了,我们下次再说。
网友评论