- 文件传输原理
- 为什么用formData传输文件
- formData用法
文件传输原理
电脑只认识二进制,为什么我们平时都感觉不到二进制的存在,因为电脑会把我们输入的信息自动转为二进制,在计算机内部都是通过二进制形式存储运算的,输出的时候又是将二进制的数据转为相应的数据显示出来。不管是文件传输和普通数据传输都是通过http协议传给后台。文件和普通数据都可以被解析成二进制数据,http传输的都是二进制数据,我们可以看成传输的都是1和0。
所有文字、图片、表单、语音、视频等文件都是二进制数据,只不过通过编辑器(浏览器)把二进制数据解释成文件的展现形式,比如用记事本打开一张图片,看到的是一堆文本,只不过图片的二进制和记事本(编辑器)的解释器不匹配,所以看起来是乱码。文件就是磁盘上的一段空间,文件的内容就是一串2进制数字(1或者0)。文件传输,就是把这串数字通过http协议传过去。服务器端,接到这段数据之后,按照协议规定的格式
,把这串数字取出来,然后创建一个空文件(分配一段空间),然后把这段数字写进去,就成了一个跟上传文件完全一致的新文件。
MIME(多用途互联网邮件扩展)
我们的电子邮件系统,一般是使用SMTP(简单邮件传输协议)将邮件从客户端发往服务器端,邮件客户端使用POP3(邮局协议,第3版本)或IMAP(交互邮件访问协议)从服务器端获取邮件。
SMTP协议一开始是基于纯ASCII文本的,对于二进制文件(比如邮件附件中的图像、声音等)的处理并不好,所以后来新增MIME标准来编码二进制文件,使其能够通过SMTP协议传输。
总结:所有信息都会被计算机转为二进制数据,然后通过http传输给后台,后台返回的也是二进制数据然后会被浏览器解析成相应的数据展示出来
为什么用formData传输文件
文件传输和普通数据传输的数据格式
是不同的,也就是content-type(文档属于什么MIME类型)是不同的,普通的数据是application/json,告诉服务器消息主体是序列化的json字符串,直接传给后台就可以了,文件数据是multipart/form-data,告诉服务器消息主体是表单形式的数据格式,这样子服务器就知道怎样分别解析它们。
formData用法
利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用ajax方法来异步的提交这个"表单"。使用FormData的最大优点就是我们可以异步上传一个二进制文件。文件、语音、视频等都是二进制文件。
方法
- append():在数据末尾添加数据
2.set():设置修改数据(值不存在就会添加,值存在就会修改)
3.get():获取相应的第一个值
4.getAll():获取相应的所有值
5.has():判断是否存在相应的key值
6.delete():删除相应的数据
FileReader
FileReader对象允许Web应用程序异步读取存储在用户计算机上的文件的内容,使用File或Blob对象指定要读取的文件或数据。
属性
1.FileReader.error:表示读取文件时发生的错误
2.FileReader.readState:表示读取的状态(0为还没加载任何数据,1为数据正在被加载,2为已完成全部的读取请求)
3.FileReader.result:文件的内容。该属性只有在读取操作完成后才有效。
事件处理
1.FileReader.onabort:该事件在读取操作被中断时触发
2.FileReader.onerror:该事件在读取操作发生错误时触发
3.FileReader.onload:该事件在读取操作完成时触发
方法
FileReader.readAsDataURL():开始读取指定Blob中内容,一旦完成,result属性中将包含一个data:URL格式的字符串以表示所读取文件的内容。
function onUpload1(file) {
var fr = new FileReader();
fr.readAsDataURL(file); // 将文件读取为Data URL
fr.onload = function () {
var result = fr.result;
if (/image/g.test(file.type)) {
var img = $('<img src="' + result + '">');
$('.preview1').html('').append(img);
} else if (/video/g.test(file.type)) {
var vidoe = $('<video controls src="' + result + '">');
$('.preview1').html('').append(vidoe);
}
}
}
总结:formData是向后台传输文件,fileReader是读取文件,实现预览
File对象
File对象是获取的文件信息。通常情况下,File对象是来自用户在一个 <input> 元素上选择文件后返回的FileList对象,也可以是来自由拖放操作生成的DataTransfer对象。File对象继承了Blob接口的属性,是特殊类型的Blob,且可以用在任意Blob类型的context中,比如说,FileReader,URL.createObjectURL()等都可以处理Blob和File。
Blob对象(二进制)
因为服务器的限制,会限制每一次上传到服务器的文件大小不能超过某个值,但是文件是大尺寸二进制数据,所以无法直接上传,这时候就需要用到Blob对象来处理。BLOB (binary large object),二进制大对象,是一个存储二进制文件的容器,里面可以储存大量的二进制编码格式的数据。
生成 Blob 对象有两种方法:一种是使用 Blob 构造函数,另一种是对现有的 Blob 对象使用 slice 方法切出一部分。
(1)Blob 构造函数,接受两个参数。第一个参数是一个包含实际数据的数组,第二个参数是数据的类型,这两个参数都不是必需的。
(2)Blob 对象的 slice 方法,将二进制数据按照字节分块,返回一个新的 Blob 对象。
普通数据或者文件都可以转为blob对象上传到服务器,不过blob构造函数的第二个参数需要设置不同的数据类型。
createObjectURL
调用 URL 对象的 createObjectURL 方法,传入一个 File 对象或者 Blob 对象,能生成一个链接。
var objecturl = window.URL.createObjectURL(blob);
上面的代码会对二进制数据生成一个 URL,这个 URL 可以放置于任何通常可以放置 URL 的地方,比如 img 标签的 src 属性。需要注意的是,即使是同样的二进制数据,每调用一次 URL.createObjectURL 方法,就会得到一个不一样的 URL。
function onUpload2 (file) {
var blob = new Blob([file]), // 文件转化成二进制文件
url = URL.createObjectURL(blob); //转化成url
if (/image/g.test(file.type)) {
var img = $('<img src="' + url + '">');
img[0].onload = function(e) {
URL.revokeObjectURL(this.src); // 释放createObjectURL创建的对象
}
$('.preview2').html('').append(img);
} else if (/video/g.test(file.type)) {
var video = $('<video controls src="' + url + '">');
$('.preview2').html('').append(video);
video[0].onload = function(e) {
URL.revokeObjectURL(this.src); // 释放createObjectURL创建的对象
}
}
revokeObjectURL
createObjectURL生成url 的存在时间,等同于网页的存在时间,一旦网页刷新或卸载,这个 URL 就失效。(File 和 Blob 又何尝不是这样呢)除此之外,也可以手动调用 URL.revokeObjectURL 方法,使 URL 失效。
DataURI对象(Base64 编码)
Base64 编码之所以称为 Base64,是因为其使用 64 个字符来对任意数据进行编码。Base64 编码本质上是一种将二进制数据转成文本数据的方案。对于非二进制数据,是先将其转换成二进制形式,最终得到一个文本字符串。
我们可以通过FileReader 的readAsDataURL方法获得文件的DataURI
Base64 编码和Blob对象可以互相转化。