Blob,File,ArrayBuffer和FileReader

8 篇文章 0 订阅

以下兼容性IE10+

Blob

BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器。

在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。

BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。
构造方法

<script>  
  var blob = new Blob(["Hello World!"],{type:"text/plain"});  
</script>

第一个参数是将合成 Blob对象的数据数组。作用跟 BlobBuilder的append() 方法相同,类型可为 任意的strings,Blobs, 和 ArrayBuffers。

第二个参数是含有属性的将生成的新Blob的对象,这个对象的属性通常有两个:type, 即 MIME type;endings, 值可为 “transparent” (默认) 或者 “native”。

var xhr = new XMLHttpRequest();    
xhr.open("get", "mm1.jpg", true);
xhr.responseType = "blob";
xhr.onload = function() {
    if (this.status == 200) {
        var blob = this.response;  // this.response也就是请求的返回就是Blob对象
        var img = document.createElement("img");
        img.onload = function(e) {
          window.URL.revokeObjectURL(img.src); // 清除释放
        };
        img.src = window.URL.createObjectURL(blob);
        body.appendChild(img);    
    }
}
xhr.send();

File

File顾名思意就是“文件”,通常而言,表示我们使用file控件()选择的FileList对象,或者是使用拖拽操作搞出的DataTransfer对象。

这里的File对象也是二进制对象,因此,从属于Blob对象,Blob对象的一些属性与方法,File对象同样适合,且推荐使用Blob对象的属性与方法。

File对象自身也有一些属性与方法,但是,有些已经过时——不推荐使用

ArrayBuffer

Blob可以append ArrayBuffer数据,也就是Blob是个更高一级的大分类,类似领导的感觉。ArrayBuffer则是具有某种恶魔果实的尖兵。

ArrayBuffer存在的意义就是作为数据源提前写入在内存中,就是提前钉死在某个区域,长度也固定,万年不变。于是,当我们要处理这个ArrayBuffer中的二进制数据,例如,分别8位,16位,32位转换一遍,这个数据都不会变化,3种转换共享数据。

So,ArrayBuffer就是缓冲出来的打死不动的二进制对象。

注意,ArrayBuffer本身是不能读写的,需要借助类型化数组或DataView对象来解释原始缓冲区(宰割原始二进制数据)。

FileReader

创建实例

var reader = new FileReader();

FileReader方法
在线预览本地文件

var input  = document.getElementById("file");   // input file
input.onchange = function(){
    var file = this.files[0];
        if(!!file){
            var reader = new FileReader();
            // 图片文件转换为base64
            reader.readAsDataURL(file);
            reader.onload = function(){
                // 显示图片
                document.getElementById("file_img").src = this.result;
        }
    }
}

二进制数据上传

var input  = document.getElementById("file");   // input file
input.onchange = function(){
    var file = this.files[0];
        if(!!file){
            var reader = new FileReader();
            reader.readAsArrayBuffer(file);
            reader.onload = function(){
                var binary = this.result;
                upload(binary);
        }
    }
}

//文件上传
function upload(binary){
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "http://xxxx/opload");
    xhr.overrideMimeType("application/octet-stream");
    // 监听变化
    xhr.onreadystatechange = function(e){
        if(xhr.readyState===4){
            if(xhr.status===200){
                // 响应成功       
            }
        }
    }
    //直接发送二进制数据
    if(xhr.sendAsBinary){
        xhr.sendAsBinary(binary);
    }else{
        xhr.send(binary);
    }
}

URL.createObjectURL

URL.createObjectURL()方法会根据传入的参数创建一个指向该参数对象的URL. 这个URL的生命仅存在于它被创建的这个文档里. 新的对象URL指向执行的File对象或者是Blob对象.

objectURL = URL.createObjectURL(blob || file);

URL.revokeObjectURL

URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL. 当你要已经用过了这个对象URL,然后要让浏览器知道这个URL已经不再需要指向对应的文件的时候,就需要调用这个方法.

window.URL.revokeObjectURL(objectURL);

简易ajax

var $={};
$.ajax = function(options){
    //1.获取参数
    var type = options.type.toUpperCase() || ‘GET‘;
    var resDataType = options.resDataType || ‘string‘;
    var reqDataType = options.reqDataType || ‘string‘;
    var url = options.url;
    var data = options.data;
    var success = options.success;
    var fail = options.fail;
    var progress = options.progress;
    var imgType = options.imgType || ‘jpg‘;

    //2.获取xhr对象
    var xhr = $.getXhr();

    //3.建立连接
    xhr.open(type,url);
    /*指定返回数据的格式需要在发送请求之前*/
    if(resDataType===‘blob‘){
        xhr.responseType = ‘blob‘;
    }
    //4.接收数据
    xhr.onreadystatechange = function(){
        if(this.readyState===4 && (this.status>=200 && this.status<300)){
            var res;
            if(resDataType===‘json‘){
                res = JSON.parse(this.responseText);
                success.call(this,res,this.responseXML)
            }
            if(resDataType===‘blob‘){
                res = new Blob([this.response],{type:‘image/‘+imgType});
                success.call(this,res)
            }

        }
    };
//5.发送请求
    if(type===‘GET‘){
        xhr.send(null)
    }
    else if(type===‘POST‘) {
        if(progress){
            xhr.upload.onprogress = progress;
        }
        if(reqDataType===‘json‘){
            xhr.setRequestHeader(‘Content-Type‘,‘application/json;charset=UTF-8‘);
            data = JSON.stringify(data);  //只能发送字符串格式的json,不能直接发送json
        }
        if(reqDataType===‘string‘){
            xhr.setRequestHeader(‘Content-Type‘,‘application/x-www-form-urlencoded‘);
        }
        xhr.send(data);
    }
};

canvas转换为dataURL (从canvas获取dataURL)

var dataurl = canvas.toDataURL('image/png');
var dataurl2 = canvas.toDataURL('image/jpeg', 0.8);

dataURL图片数据绘制到canvas

先构造Image对象,src为dataURL,图片onload之后绘制到canvas

 var img = new Image();
 img.onload = function(){
     canvas.drawImage(img);
 };
 img.src = dataurl;

File对象转换为dataURL、Blob对象转换为dataURL

File对象也是一个Blob对象,二者的处理相同。

 function readBlobAsDataURL(blob, callback) {
     var a = new FileReader();
     a.onload = function(e) {callback(e.target.result);};
     a.readAsDataURL(blob);
 }
 //example:
 readBlobAsDataURL(blob, function (dataurl){
     console.log(dataurl);
 });
 readBlobAsDataURL(file, function (dataurl){
     console.log(dataurl);
 });

dataURL转换为Blob对象、dataURL转换为File对象

File继承于Blob,扩展了一些属性(文件名、修改时间、路径等)。绝大多数场景下,使用Blob对象就可以了。
兼容性:Edge浏览器不支持File对象构造函数,也就是Edge里不能new File()。

 function dataURLtoBlob(dataurl) {
     var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
         bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
     while(n--){
         u8arr[n] = bstr.charCodeAt(n);
     }
     return new Blob([u8arr], {type:mime});
 }
 function dataURLtoFile(dataurl, filename) {
     var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
         bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
     while(n--){
         u8arr[n] = bstr.charCodeAt(n);
     }
     return new File([u8arr], filename, {type:mime});
 }
 /* 工具方法:dataURL(base64字符串)转换为Blob对象(二进制大对象) */
 //data:image/png;base64,iVBORw0KGgoAAAANSUhEUg......
 function dataURLtoBlob(dataurl) {
     var arr = dataurl.split(',');
     var mime = arr[0].match(/:(.*?);/)[1];// 结果:   image/png
     console.log("arr[0]====" + JSON.stringify(arr[0]));//   "data:image/png;base64"
     console.log("arr[0].match(/:(.*?);/)====" + arr[0].match(/:(.*?);/));// :image/png;,image/png
     console.log("arr[0].match(/:(.*?);/)[1]====" + arr[0].match(/:(.*?);/)[1]);//   image/png
     var bstr = atob(arr[1].replace(/\s/g, ''));
     var n = bstr.length;
     var u8arr = new Uint8Array(n);
     while (n--) {
         u8arr[n] = bstr.charCodeAt(n);
     }
     return new Blob([u8arr], {type: mime});//值,类型
 }
 //example:
 var blob = dataURLtoBlob('data:text/plain;base64,YWFhYWFhYQ==');
 var file = dataURLtoFile('data:text/plain;base64,YWFhYWFhYQ==', 'test.txt');

参考资料

  1. js-用于上传的FormData与Blob
  2. 理解DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型
  3. FileReader对象
  4. URL.createObjectURL和URL.revokeObjectURL
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值