JS——blob

1、【HTML5】Blob对象

(1)写在前面:本小节主要介绍Blob对象属性及作用,通过demo介绍blob对象的应用场景。

blob对象:一直以来,JS都没有比较好的可以直接处理二进制的方法。而blob的存在,允许我们可以通过js直接操作二进制数据。

“一个blob对象就是一个包含有只读原始数据的类文件对象。blob对象中的数据并不一定得是JavaScript中的原生形式。file接口基于blob,继承了blob的功能,并且扩展支持了用户计算机上的本地文件”

Blob对象可以看作是存放二进制数据的容器,此外还可以通过blob设置二进制数据的MIME类型。

(2)创建blob

方法一:通过构造函数


var blob = new Blob(dataArr:Array<any>,opt:{type:string});

dataArr:数组,包含了要添加到blob对象中的数据,数据可以是任意多个ArrayBuffer,ArrayBufferView,blob或者DOMString对象

opt:对象,用于设置Blob对象的属性(如MIME类型)

MIME:每一个 URL 都代表着一个资源对象,而当我们请求一个网页的时候,看似只请求了一个 URI(统一资源标识符),实际上这个网页可能包含多个 URI,例如图片资源的 URI 和视频资源的 URI 等。此时有些浏览器为了加快访问速度,可能会同时开多个线程去请求 URI。也就是说其实每一个 URI 都发送了一个请求报文。而当我们的浏览器要显示或处理这些资源的时候,我们并不知道其响应的数据是什么类型的,为了区分这些资源类型,就需要用到 MIME 了。HTTP 会为每一个通过 web 传输的对象添加上 MIME 类型的数据格式标签。浏览器在读取到对应的信息后,会调用相应的程序去处理它,任何得到我们想要的结果。

第一种:创建一个装填DOMString对象的blob对象

image

第二种:创建一个装填ArrayBuffer对象的Blob对象

image

第三种:创建一个装填ArrayBufferView对象的Blob对象(ArrayBufferView可基于ArrayBuffer创建,返回值是一个类数组。如下,创建一个8字节的ArrayBuffer,在其上创建一个每个数组元素为2字节的“视图”)

image

方法二:通过Blob.slice()


此方法返回一个新的Blob对象,包含了原blob对象中指定范围内的数据

Blob.slice(start:number,end:number,contentType:string)

start:开始索引,默认为0

end:截止结束索引(不包括end)

contentType:新blob的MIME类型,默认为空字符串

image

方法三:通过canvas.toBlob()


var canvas = document.getElementById("canvas");

canvas.toBlob(function(blob){

console.log(blob);

});

2、应用场景

前面提到,file接口继承blob,继承了blob的功能并进行了扩展,故我们可以像使用Blob一样使用File对象

分片上传


通过Blob.slice方法,可以将大文件分片,轮循向后台提交各文件片段,即可实现文件的分片上传。

分片上传逻辑如下:

获取要上传文件的File对象,根据chunk(每片大小)对文件进行分片

通过post方法轮循上传每片文件,其中url中拼接querystring用于描述当前上传的文件信息;post body中存放本次要上传的二进制数据片段

接口每次返回offset,用于执行下次上传

下面是分片上传的简单实现:

initUpload();//初始化上传functioninitUpload(){
 
    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);
        }
    }
}
// 执行上传
functionupload(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);
        }
    }
}

 

1人点赞

 

前端知识

 



作者:彼得朱
链接:https://www.jianshu.com/p/e45522c7f6c9
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值