
构造函数
创建blob对象本质上和创建一个其他对象的方式是一样的,都是使用Blob() 的构造函数来进行创建。 构造函数接受两个参数:
第一个参数为一个数据序列,格式可以是ArrayBuffer, ArrayBufferView, Blob, DOMString
第二个参数是一个包含以下两个属性的对象
var data1 = "a"; var blob1 = new Blob([data1]); console.log(blob1); //
slice方法
Blob对象有一个slice方法,返回一个新的 Blob对象,包含了源 Blob对象中指定范围内的数据。
slice(start, end, contentType)
start: 可选,代表 Blob 里的下标,表示第一个会被会被拷贝进新的 Blob 的字节的起始位置。如果传入的是一个负数,那么这个偏移量将会从数据的末尾从后到前开始计算。
end: 可选,代表的是 Blob 的一个下标,这个下标-1的对应的字节将会是被拷贝进新的Blob 的最后一个字节。如果你传入了一个负数,那么这个偏移量将会从数据的末尾从后到前开始计算。
contentType: 可选,给新的 Blob 赋予一个新的文档类型。这将会把它的 type 属性设为被传入的值。它的默认值是一个空的字符串。
var data = "abcdef"; var blob1 = new Blob([data]); var blob2 = blob1.slice(0,3); console.log(blob1); //
slice用于文件分片上传
分片上传逻辑如下:
获取要上传文件的File对象,根据chunk(每片大小)对文件进行分片
通过post方循上传每片文件,其中url中拼接querystring用于描述当前上传的文件信息;post body中存放本次要上传的二进制数据片段
接口每次返回offset,用于执行下次上传
initUpload();
//初始化上传
function initUpload() {
var chunk = 100 * 1024; //每片大小
var input = document.getElementById("file"); //input file
input.onchange = function (e) {
var file = this.files[0];
var query = {};
var chunks = [];
if (!!file) {
var start = 0;
//文件分片
for (var i = 0; i < Math.ceil(file.size / chunk); i++) {
var end = start + chunk;
chunks[i] = file.slice(start , end);
start = end;
}
// 采用post方法上传文件
// url query上拼接以下参数,用于记录上传偏移
// post body中存放本次要上传的二进制数据
query = {
fileSize: file.size,
dataSize: chunk,
nextOffset: 0
}
upload(chunks, query, successPerUpload);
}
}
}
// 执行上传
function upload(chunks, query, cb) {
var queryStr = Object.getOwnPropertyNames(query).map(key => {
return key + "=" + query[key];
}).join("&");
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://xxxx/opload?" + queryStr);
xhr.overrideMimeType("application/octet-stream");
//获取post body中二进制数据
var index = Math.floor(query.nextOffset / query.dataSize);
getFileBinary(chunks[index], function (binary) {
if (xhr.sendAsBinary) {
xhr.sendAsBinary(binary);
} else {
xhr.send(binary);
}
});
xhr.onreadystatechange = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var resp = JSON.parse(xhr.responseText);
// 接口返回nextoffset
// resp = {
// isFinish:false,
// offset:100*1024
// }
if (typeof cb === "function") {
cb.call(this, resp, chunks, query)
}
}
}
}
}
// 每片上传成功后执行
function successPerUpload(resp, chunks, query) {
if (resp.isFinish === true) {
alert("上传成功");
} else {
//未上传完毕
query.offset = resp.offset;
upload(chunks, query, successPerUpload);
}
}
// 获取文件二进制数据
function getFileBinary(file, cb) {
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function (e) {
if (typeof cb === "function") {
cb.call(this, this.result);
}
}
}Blob URL
blob协议的url使用时就像平时使用的url一样,可以作为图片请求地址,也可以作为文件请求地址。格式:
blob:http://XXX
下面是一个下载文件的示例,直接调用即可实现文件下载
// file是要下载的文件(blob对象)
downloadHandler: function (file, fileName) {
let link = document.createElement('a')
link.href = window.URL.createObjectURL(file)
link.download = fileName
link.click()
window.URL.revokeObjectURL(link.href)
if (navigator.userAgent.indexOf('Firefox') > -1) {
const a = document.createElement('a')
a.addEventListener('click', function (e) {
a.download = fileName
a.href = URL.createObjectURL(file)
})
let e = document.createEvent('MouseEvents')
e.initEvent('click', false, false)
a.dispatchEvent(e)
}
}在从后台获取的数据接口中把返回类型设置为blob
var x = new XMLHttpRequest(); x.responseType = 'blob'; // 返回一个blob对象
Blob URL和Data URL的区别
Blob URL

Data URL

总结
