这里主要介绍Blob
对象和FileReader
对象
Blob对象
1、什么是Blob?
百度百科
BLOB (binary large object),二进制大对象,是一个可以存储二> 进制文件的容器。
在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类> 型。
BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,> 由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下> > 载或者存放到一个数据库)。维基百科
二进制大型对象(英语:binary large object ,或英语:basic > > large object,缩写为Blob、BLOB、BLOb),在数据库管理系> > 统中,将二进制数据存储为一个单一个体的集合。Blob通常是视> 频、声音或多媒体文件。
上面分别是来自百度百科
和维基百科
对Blob
的解释,由解释可知,Blob对象就是一个二进制大对象
在HTML5中,新增了Blob对象,用来代表原始二进制数据,而文件对象即file对象
也继承了Blob对象,对于file对象的相关介绍请参考上一篇文章文件API(篇一)
Blob对象的type
属性表示Blob对象的MIME类型(未知类型type属性为空),由于file对象继承了blob对象,所以我们可以通过type属性来判断文件的类型。
小案例(在进行上传操作时通过判断文件类型判断文件是否上传)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件操作</title>
</head>
<body>
<input type="file" id="file" multiple>
<button id="btn">文件上传</button>
<script>
var file_input = document.getElementById('file')
var uplaod_btn = document.getElementById('btn')
uplaod_btn.addEventListener('click', upload, true)
function upload () {
// file_input.files表示上传的文件对象数组
var file_list = file_input.files
var len = file_list.length
for(var i = 0; i < len; i++) {
// 判断是否是图片文件
if ( /^image\/\w+$/.test(file_list[i].type) ) {
console.log(file_list[i].type + '类型是图片类型')
}
else {
console.log(file_list[i].type + '类型不是是图片类型')
continue // 跳过上传
}
}
}
</script>
</body>
</html>
值得说明的是上传的文件可以通过修改文件后缀名来达到以假乱真的效果,即修改文件的后缀名可以达到改变文件type,从而上传的效果
2、Blob对象创建的两种方式
1)、Blob() 构造函数创建Blob对象
Blob(blobParts[, options]) // blobParts为数组类型
返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成。
var debug = {hello: "world"};
var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});
2)、通过BlobBuilder接口创建Blob对象(该方式现在已经废弃,这里不再说明)
3、Blob对象的方法
slice:
Blob.slice([start,[ end ,[contentType]]])
返回一个新的 Blob对象,包含了源 Blob对象中指定范围内的数据。
参数说明
start:代表复制位置在Blob对象所代表的原始二进制数据中的位置(非复制的起始位置)
end:代表复制位置在Blob对象所代表的原始二进制数据中的位置(非复制的结束位置)
contentType:新创建的Blob对象的MIME类型
复制规则说明
1、三个参数均省略。原样复制Blob对象
2、start = 0,则起始位置为blob对象的第一个字节
3、star < 0,start + size >= 0,则起始位置为 start + size
3、star < 0,start + size < 0,则起始位置为blob对象的第一个字节
4、start > 0,start >= size,则起始位置为size
5、start > 0,start < size,则起始位置为start
6、end < 0,end + size >= 0,则终止位置为end + size
7、end < 0,end + size < 0,则终止位置为blob对象的开始位置(第一个字节)
8、end > 0,end >= size,则终止位置为size
9、end > 0,end < size,则终止位置为end
当复制起始位置大于等于复制终止位置时,则slice方法复制从复制起始位置开始到复制终止位置之间的数据;当复制起始位置小于复制终止位置时,则slice方法复制从复制终止位置开始到复制起始位置之间的数据。
<script>
var file_input = document.getElementById('file')
var uplaod_btn = document.getElementById('btn')
uplaod_btn.addEventListener('click', upload, true)
function upload () {
// 获取file对象
var file = file_input.files[0]
if (file) {
// 复制file对象
var fileCloneOne = file.slice()
var fileCloneTwo = file.slice(0, file.size)
// 复制file对象的后半部分
var fileChunkFromEnd = file.slice(-(Math.round(file.size / 2)))
// 复制file对象的前半部分
var fileChunkFromStart = file.slice(0, Math.round(file.size / 2))
// 从起始位置复制到数据结尾处之前的150个字节处,并设置MIME类型
var fileNoMetaData = file.slice(0, -150, "application/experimental")
console.log(fileCloneOne)
console.log(fileCloneTwo)
console.log(fileChunkFromEnd)
console.log(fileChunkFromStart)
console.log(fileNoMetaData)
}
}
</script>
结果:
FileReader对象
1、FileReader对象的方法
readAsBinaryString:将Blob对象或文件中的数据读取为二进制字符串,通常我们将其传到服务端,服务端通过这段字符串存储文件
readAsText:将Blob对象或文件中的数据读取为文本数据,读取的结果即为文件中的内容
readAsDataURL:将Blob对象或文件中的数据读取为DataURL,通过特殊格式的URL读入页面
readAsArrayBuffer:将Blob对象或文件中的数据读取为ArrayBuffer对象
2、FileReader对象的事件
onabort
当读取操作被中止时调用.
onerror
当读取操作发生错误时调用.
onload
当读取操作成功完成时调用.
onloadend
当读取操作完成时调用,不管是成功还是失败.该处理程序在onload或者onerror之后调用.
onloadstart
当读取操作将要开始之前调用.
onprogress
在读取数据过程中周期性调用.
小案例一(将文件中的数据读取为各种对象类型)
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>FileReader</title>
</head>
<body>
<label for="file">请选择一个文件</label>
<input type="file" id="file" />
<button onClick="readAsDataURL()">读取图像</button>
<button onClick="readAsBinaryString()">读取二进制文件</button>
<button onClick="readAsText()">读取文本文件</button>
<div id="result"></div>
<script>
var file,
reader,
result = document.getElementById('result')
function have_file (file) {
return file ? true : false
}
function readAsDataURL () {
file = document.getElementById('file').files[0]
if (!have_file (file)) {
alert('清请先上传文件')
return false
}
reader = new FileReader()
if (!/image\/\w+/.test(file.type)) {
alert('上传的文件不是图像文件')
return false
}
reader.readAsDataURL(file)
reader.onload = function (e) {
result.innerHTML = "<img src='" + this.result + "' alt='' />"
}
}
function readAsBinaryString () {
file = document.getElementById('file').files[0]
if (!have_file (file)) {
alert('清请先上传文件')
return false
}
reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = function (e) {
result.innerHTML = this.result
}
}
function readAsText () {
file = document.getElementById('file').files[0]
if (!have_file (file)) {
alert('清请先上传文件')
return false
}
reader = new FileReader()
reader.readAsText(file)
reader.onload = function (e) {
console.log('load')
result.innerHTML = this.result
}
}
</script>
</body>
</html>
小案例二(FileReader对象事件触发的先后顺序)
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>FileReader</title>
</head>
<body>
<label for="file">请选择一个文件</label>
<input type="file" id="file" />
<button onClick="readAsText()">读取文本文件</button>
<div id="result"></div>
<script>
var file,
reader,
result = document.getElementById('result')
function have_file (file) {
return file ? true : false
}
function readAsText () {
file = document.getElementById('file').files[0]
if (!have_file (file)) {
alert('清请先上传文件')
return false
}
reader = new FileReader()
reader.readAsText(file)
// fileReader 对象事件
reader.onload = function (e) {
console.log('load')
result.innerHTML = this.result
}
reader.onprogress = function (e) {
console.log('progress')
}
reader.onabort = function (e) {
console.log('abort')
}
reader.onerror = function (e) {
console.log('error')
}
reader.onloadstart = function (e) {
console.log('loadstart')
}
reader.onloadend = function (e) {
console.log('loadend')
}
}
</script>
</body>
</html>
结果:
不当之处,欢迎指出…