js中Blob对象⼀般⽤法
前段时间研究遇到了Blob对象,在这⾥做⼀下笔记。
在⼀般的Web开发中,很少会⽤到Blob,但Blob可以满⾜⼀些场景下的特殊需求。Blob,Binary Large Object的缩写,代表⼆进制类型的⼤对象。Blob的概念在⼀些数据库中有使⽤到,例如,MYSQL中的BLOB类型就表⽰⼆进制数据的容器。在Web
中,Blob类型的对象表⽰不可变的类似⽂件对象的原始数据,通俗点说,就是Blob对象是⼆进制数据,但它是类似⽂件对象的⼆进制数据,因此可以像操作File对象⼀样操作Blob对象,实际上,File继承⾃Blob。
Blob基本⽤法
创建
可以通过Blob的构造函数创建Blob对象:
Blob(blobParts[, options])
参数说明:
blobParts:数组类型,数组中的每⼀项连接起来构成Blob对象的数据,数组中的每项元素可以是ArrayBuffer(⼆进制数据缓冲区), ArrayBufferView,Blob,DOMString。或其他类似对象的混合体。
options:可选项,字典格式类型,可以指定如下两个属性:
type,默认值为"",它代表了将会被放⼊到blob中的数组内容的MIME类型。
endings,默认值为"transparent",⽤于指定包含⾏结束符\n的字符串如何被写⼊。它是以下两个值中的⼀个: "native",表⽰⾏结束符会被更改为适合宿主操作系统⽂件系统的换⾏符; "transparent",表⽰会保持blob中保存的结束符不变。
举个栗⼦:
var data1 = "a";
var data2 = "b";
var data3 = "<div style='color:red;'>This is a blob</div>";
var data4 = { "name": "abc" };
var blob1 = new Blob([data1]);
var blob2 = new Blob([data1, data2]);
var blob3 = new Blob([data3]);
var blob4 = new Blob([JSON.stringify(data4)]);
var blob5 = new Blob([data4]);
var blob6 = new Blob([data3, data4]);
console.log(blob1);  //输出:Blob {size: 1, type: ""}
console.log(blob2);  //输出:Blob {size: 2, type: ""}
console.log(blob3);  //输出:Blob {size: 44, type: ""}
console.log(blob4);  //输出:Blob {size: 14, type: ""}
console.log(blob5);  //输出:Blob {size: 15, type: ""}
console.log(blob6);  //输出:Blob {size: 59, type: ""}
size代表Blob对象中所包含数据的字节数。这⾥要注意,使⽤字符串和普通对象创建Blob时的不同,blob4使⽤通过JSON.stringify把data4对象转换成json字符串,blob5则直接使⽤data4创建,两个对象的size分别为14和15。blob4的size等于14很容易理解,因为
JSON.stringify(data4)的结果为:"{"name":"abc"}",正好14个字节(不包含最外层的引号)。blob5的size等于15是如何计算⽽来的呢?实际上,当使⽤普通对象创建Blob对象时,相当于调⽤了普通对象的toString()⽅法得到字符串数据,然后再创建Blob对象。所以,blob5保存的数据是"[object Object]",是15个字节(不包含最外层的引号)。
slice⽅法
Blob对象有⼀个slice⽅法,返回⼀个新的Blob对象,包含了源Blob对象中制定范围内的数据。
参数说明:
start:可选,代表⾥的下标,表⽰第⼀个会被会被拷贝进新的的字节的起始位置。如果传⼊的是⼀个负数,那么这个偏移量将会从数据的末尾从后到前开始计算。
end:可选,代表的是的⼀个下标,这个下标-1的对应的字节将会是被拷贝进新的的最后⼀个字节。如果你传⼊了⼀个负数,那么这个偏移量将会从数据的末尾从后到前开始计算。
contentType:可选,给新的赋予⼀个新的⽂档类型。这将会把它的 type 属性设为被传⼊的值。它的默认值是⼀个空的字符串。
举个栗⼦:
var data = "abcdef";
var blob1 = new Blob([data]);
var blob2 = blob1.slice(0,3);
console.log(blob1);  //输出:Blob {size: 6, type: ""}
console.log(blob2);  //输出:Blob {size: 3, type: ""}
通过slice⽅法,从blob1中创建出⼀个新的blob对象,size等于3。
Blob对象能够添加到表单中,作为上传数据使⽤:
const content = '<a id="a"><b id="b">hey!</b></a>';
const blob = new Blob([content], {type: 'text/xml'});
formData.append('webmasterfile', blob);
Blob使⽤场景
分⽚上传
前⾯已经说过,File继承字Blob,因此我们可以调⽤slice⽅法对⼤⽂件进⾏分⽚上传。代码:
function uploadFile(file) {
var chunkSize = 1024 * 1024; //每⽚1M⼤⼩
var totalSize = file.size;
var chunkQuantity = il(totalSize/chunkSize); //分⽚总数
var offset = 0; //偏移量
var reader = new FileReader();
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.overrideMineType("application/octet-stream");
adyState === 4 && xhr.status ===200) {
++offset;
if(offset === chunkQuantity) {
alerrt("上传完成");
} else if(offset === chunckQuantity-1) {
blob = file.slice(offset*chunkSize, totalSize);
} else {
blob = file.slice(offset*chunkSize, (offset+1)*chunckSize);
}
}else {
alert("上传出错");
}
}
if(xhr.sendAsBinary) {
xhr.sendAsBinary(sult);
} else {
xhr.send(sult);
}
}
var blob = file.slice(0, chunkSize);
}
这段代码还可以进⼀步丰富,⽐如显⽰当前上传进度,使⽤多个XMLHttpRequest对象并⾏上传对象(需要传递分⽚数据得位置参数给服务器端)等。
Blob URL
⽂件下载地址
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blob Test</title.
<script>
function createDownloadFile() {
var content = "Blob Data";
var blob = new Blob([content]);
var link = ElementByTageName('a')[0];
link.download = "file";
link.href = ateObjectURL(blob);
}
</script>
</head>
<body>
<a>下载</a>
</body>
</html>
点击下载按钮,浏览器将会下载⼀个名为file得⽂件,⽂件得内容是:Blob Data。通过Blob对象,我们在前端代码中就可以动态⽣成⽂件,提供给浏览器下载。打开Chrome浏览器调试窗⼝,在Elements标签下可以看到⽣成得Blob URL:
[图⽚上传失败...(image-130a5a-1551669191720)]
图⽚资源地址
为图⽚⽂件创建⼀个Blob URL,赋值给标签:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blob Test</title>
<script>
function handleFile(e) {
var file = e.files[0];
var blob = ateObjectURL(file);
var img = ElementByTagName("img")[0];
img.src = blob;
}
}
</script>
</head>
<body>
<input type="flie" accept="image/*" onchange="handleFile(this)" />
<br/>
<img >
</body>
</html>
imput中选择得图⽚会在这⾥显⽰出来:
[图⽚上传失败...(image-c20d1f-1551669191720)]
同时,可以在Network标签栏,发现这个Blob URL得请求信息:
[图⽚上传失败...(image-fa2288-1551669191720)]
这个请求信息和我们平常使⽤Http URL获取得图⽚⼏乎完全⼀样。
vokeObjectURL()
在每次调⽤createObjectURL()⽅法时,都会创建⼀个新的URL对象,即使你已经⽤相同的对象作为参数
创建过。当不再需要这些URL对象时,每个对象必须通过调⽤vokeObjectURL()⽅法来释放。浏览器会在⽂档退出时⾃动释放它们,但是为了获得最佳性能和内存使⽤状况,你应该在安全的时机主动释放掉它们。
vokeObjectURL(objectURL);
我们还可以使⽤Data URL加载图⽚资源:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blob Test</title>
<script>
function handleFile(e) {
var file = e.files[0];
var fileReader = new FileReader();
var img = ElementByTagName("img")[0];
img.src = sult;
创建html文件
}
}
</script>
</head>
<body>
<input type="file" accept="image/*" onchange="handleFile(this)" />
</br>
<img >
</body>
</html>
Data URL对⼤家来说并不陌⽣,Web性能优化有⼀项措施:把⼩图⽚⽤base64编码直接嵌⼊到HTML⽂件中,实际就是利⽤了Data URL来获取图⽚数据。
那么Blob URL和Data URL有什么区别呢?
1. Blob URL得长度⼀般⽐较短,但Data URL因为直接存储图⽚base64编码后得数据,往往很长。当显⽰⼤图⽚时,使⽤Blob URL更
优。
2. Blob URL可以⽅便的使⽤XMLHttpRequest获取源数据,例如:
var blobUrl = ateObkectURL(new Blob(['Test'], {type: 'text/plain'}));
var xhr = new XMLHttpRequest();
//如果是指sponseType = 'blob',将返回⼀个Blob对象,⽽不是⽂本;
//sponseType = 'blob';
sponseText);
}
xhr.open('get', blobUrl);
xhr.send();
对于Data URL,并不是所有浏览器都⽀持通过XMLHttpRequest获取源数据的。
1. Blob URL只能在当前应⽤内部使⽤,把Blob URL复制到浏览器的地址栏中,是⽆法获取数据的。Data URL相⽐之下,就有很好的移
植性,你可以在任意浏览器使⽤。
除了可以⽤作图⽚资源的⽹络地址,Blob URL也可以⽤作其他资源的⽹络地址,例如html⽂件、json⽂件等,为了保证浏览器能正确的解析Blob URL返回的⽂件类型,需要在创建Blob对象时指定相应的type:
//创建HTML⽂件的Blob URL
var data = "<div style='color:red;'This is a blob</div>";
var blob = new Blob([data], {type: 'text/html'}); // 'application/json'
var blobUrl = ateObjectURL(blob);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。