以下兼容性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();
在线预览本地文件
var input = document.getElementById("file"); // input file
input.onchange = function(){var file = this.files[0];if(!!file){var reader = new FileReader();// 图片文件转换为base64reader.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/pngconsole.log("arr[0]====" + JSON.stringify(arr[0]));// "data:image/png;base64"console.log("arr[0].match(/:(.*?);/)====" + arr[0].match(/:(.*?);/));// :image/png;,image/pngconsole.log("arr[0].match(/:(.*?);/)[1]====" + arr[0].match(/:(.*?);/)[1]);// image/pngvar 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');
参考资料
- js-用于上传的FormData与Blob
- 理解DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型
- FileReader对象
- URL.createObjectURL和URL.revokeObjectURL