当前位置: 首页 > Web前端 > HTML

使用Blob进行文件上传

时间:2023-04-02 19:47:37 HTML

Blob,BinaryLargeObject的缩写,二进制类型的大对象,代表不可变的原始数据一个字节序列中的字节总数,以及一个类型属性,它是一个小写的ASCII编码字符串,表示媒体类型的字节序列。size:返回字节序列的大小(以字节为单位)。在获取时,符合要求的用户代理必须返回FileReader或FileReaderSync对象可以读取的总字节数,如果blob没有字节可读取,则返回0。type:表示媒体类型Blob的小写ASCII编码字符串。在获取时,用户代理必须返回一个小写的Blob类型的ASCII编码字符串,以便在转换为字节序列时它是可解析的MIME类型,或者如果无法确定类型则返回空字符串(0字节)。构造函数创建blob对象的方式与创建另一个对象的方式基本相同,即使用Blob()构造函数创建它。构造函数接受两个参数:第一个参数是一个数据序列,格式可以是ArrayBuffer,ArrayBufferView,Blob,DOMString第二个参数是一个对象,包含以下两个属性类型:MIME类型,结尾:确定第一个的数据格式参数。默认为“transparent”,它指定包含行终止符n的字符串如何写入。它是以下两个值之一:“native”,表示行尾将更改为适合主机操作系统文件系统的换行符;“透明”,表示保存在blob中的结束字符将保持不变。vardata1="a";varblob1=newBlob([data1]);控制台日志(blob1);//输出:Blob{size:1,type:""}vardebug={hello:"world"};varblob=newBlob([JSON.stringify(debug,null,2)],{type:'application/json'});console.log(blob)//输出Blob(22){size:22,type:"application/json"}//创建一个8字节的ArrayBuffer,在其上创建一个“视图”,每个数组元素2个字节varabf=newArrayBuffer(8)varabv=newInt16Array(abf)varbolb_ArrayBuffer=newBlob(abv,{type:'text/plain'})console.log(bolb_ArrayBuffer)//输出Blob(4){size:4,type:"text/plain"}slice方法Blob对象有一个slice方法返回一个新的Blob对象,该对象包含源Blob对象指定范围内的数据。slice(start,end,contentType)start:可选,表示blob中的下标,表示将被复制到新blob中的第一个字节的起始位置。如果传入负数,则从数据末尾从后向前计算偏移量。end:可选,表示Blob的一个下标,下标-1对应的字节将是复制到新Blob中的最后一个字节。如果传入负数,则偏移量将从数据的末尾向后计算。contentType:可选,将新文档类型分配给新blob。这会将其类型属性设置为传入的值。其默认值为空字符串。vardata="abcdef";varblob1=newBlob([data]);varblob2=blob1.slice(0,3);console.log(blob1);//输出:Blob{size:6,type:""}console.log(blob2);//Output:Blob{size:3,type:""}slice用于文件分片上传分片并发,将一个大文件拆分成多块并发上传,大大提高了大文件的上传速度。当网络问题导致传输错误时,只需要重传错误的段,而不是整个文件。另外,分片传输可以实时跟踪上传进度。分片上传的逻辑如下:获取待上传文件的File对象,将文件按照chunk(每个分片的大小)分片,通过post方法依次上传每个分片,其中url中的querystring用于描述当前上传的文件信息;postbody存放的是本次要上传的二进制数据片段。接口每次返回offset,用于执行下一次上传initUpload();//初始化上传函数initUpload(){varchunk=100*1024;//每块的大小varinput=document.getElementById("file");//输入文件input.onchange=function(e){varfile=this.files[0];变种查询={};变量块=[];如果(!!文件){varstart=0;//文件碎片for(vari=0;i{returnkey+"="+query[key];}).join("&");varxhr=newXMLHttpRequest();xhr.open("POST","http://xxxx/opload?"+queryStr);xhr.overrideMimeType("application/octet-stream");//获取postbody中的二进制数据varindex=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){varresp=JSON.parse(xhr.responseText);//接口返回nextoffset//resp={//isFinish:false,//offset:100*1024//}if(typeofcb==="function"){cb.call(this,resp,chunks,query)}}}}}//执行函数successPerUpload(resp,chunks,query){if(resp.isFinish===true){alert("上传成功");}else{//未完成的上传query.offset=resp.offset;上传(块,查询,successPerUpload);}}//获取文件二进制数据functiongetFileBinary(file,cb){varreader=newFileReader();reader.readAsArrayBuffer(文件);reader.onload=function(e){if(typeofcb==="function"){cb.call(this,this.result);}}}BlobURLblob协议的url和通常的url一样,可以作为图片请求地址或者文件请求地址格式:blob:http://XXXURL.createObjectURL(blob)创建一个链接URL.revokeObjectURL(url)下面是一个下载文件的例子,可以调用直接下载//file是要下载的文件(blobobject)downloadHandler:function(file,fileName){letlink=document.createElement('a')link.href=window.URL.createObjectURL(file)link.download=fileNamelink.click()window.URL.revokeObjectURL(link.href)if(navigator.userAgent.indexOf('Firefox')>-1){consta=document.createElement('a')a.addEventListener('click',function(e){a.download=fileNamea.href=URL.createObjectURL(file)})lete=document.createEvent('MouseEvents')e.initEvent('click',false,false)a.dispatchEvent(e)}}返回从中获取的数据接口后台类型设置为blobvarx=newXMLHttpRequest();x.responseType='blob';//返回一个blob对象BlobURL和DataURL的区别BlobURLDataURLBlobURL一般长度较短,而DataURL直接存储图片base64编码的数据往往很长。如上图所示,浏览器在显示DataURL时使用了省略号(...)。显示大图像时,使用BlobURL提供更好的可能性。BlobURL可以方便地使用XMLHttpRequest获取源数据。例如,将XMLHttpRequest返回的数据类型设置为blobBlobURL,只能在当前应用内使用。复制BlobURL到浏览器地址栏无法获取数据。相比之下,DataURL非常便携,可以在任何浏览器中使用。