BLOB详解

BLOBBinary Large Object的缩写,意为“大的二进制对象”。javascript

《JavaScript权威指南》中对BLOB的描述:css

A Blob is an opaque reference to, or handle for, a chunk of data.
Blobs oten represent chunks of data from an external source such as a local file, a URL, or a database.html

BLOB的两个特色:java

  • large: Blob表示巨大的数据块,如视频文件
  • opaque(不透明): 咱们对BLOB能够作到操做仅限于设置字节长度、获取MIME类型、截取更小的BLOB。

Blob操做

获取Blob的方式:

1. Blob支持结构化克隆算法(structured clone algorithm),因此能够经过消息事件从另一个窗口或线程中获取blob对象

2. 从客户端数据库取出blob

3. 经过http从网络上下载blob

function getBlob(url, callback){
    let xhr = new XMLHTTPRequest();
    xhr.open("GET", url);
    xhr.responseType = "blob";
    xhr.onload = function() {
        callback(xhr.response); // 注意,是 .response 而不是 .responseText 
    }
    // 若是下载的blob很大,可使用 onprogress 获取下载进度
    xhr.send(null);
}
复制代码

4. 经过BlobBuilder建立新的blob对象

var bb = new BlobBuilder();
bb.append('this blob contains this text and 10 big-endian 32-bit signed ints.'); // 写入字符串
bb.append('\0'); // 写入空字符,表示字符串已结束
var arraybuffer = new ArrayBuffer(4*10);
var dataView = new DataView(arrayBuffer);
for(var i=0; i<10; i++){
    dataView.setInt32(i*4, i);
}
bb.append(arrayBuffer); // 写入ArrayBuffer
var blob = bb.getBlob('x-optional/mime-type-here'); // 获取blob,并指定mime类型
复制代码

5. 客户端JS中的File对象是BLob的子类型。File是一个有名称(name)和修改日期(lastModifiedDate)属性的Blob数据。能够经过<input type="file">元素标签或者拖拽接口获取File对象。

<input type="file" id="ele">

const selectedFiles = document.getElementById("ele").files
// files属性是的值是一个File对象数组,包含用户选择的0个或多个文件的file对象。
for (let i = 0; i < selectedFiles.length; i++) {
    const f = selectedFiles[i]
    console.log(f.name, f.lastModifiedDate)
    console.log(f.size, f.type) // Blob对象的属性
}
复制代码

对Blob对象可作以下操做:

1. 建立Blob URL

Blob url 是指向存储在浏览器缓存或磁盘中的blob的一个引用。web

经过createObjectURL()获取指向Blob数据的url blob://,而且在DOM、css中使用blob url,用法和普通的url同样。算法

Blob URL 受同源策略限制,只有在同源的document中是合法的。数据库

Blob URL不是不变的,建立Blob URL的document被用户关闭后,Blob URL就会变成无效的。数组

blob://URL工做方式和http://URL相似,当请求blob://URL时浏览器行为和http请求相同。若是请求的blob url再也不合法,浏览器必须返回404(Not Found)状态码。当请求不一样源的blob url时,浏览器必须返回403(Not Allowed)。 Blob URL 只容许经过 GET 请求,请求成功须要返回状态码200,而且response.header.Content-Type = Blob.type浏览器

下面的代码是经过blob url预览拖拽到指定区域的图片文件。缓存

<!DOCTYPE html>
<html>
    <head>
        <script> // 处理浏览器兼容问题 var getBlobURL = (window.URL && URL.createObjectURL.bind(URL)) || (window.webkitURL && webkitURL.createObjectURL.bind(URL)) || window.createObjectURL; // 释放以前经过createObjectURL建立的对象 var revokeBlobURL = (window.URL && URL.revokeObjectURL.bind(URL)) || (window.webkitURL && webkitURL.revokeObjectURL.bind(URL)) || window.revokeObjectURL; window.onload = function(){ var droptarget = document.getElementById('droptarget'); droptarget.ondragenter = function (e) { var types = e.dataTransfer.types; if (!types || (types.contains && types.contains('Files')) || (types.indexOf && types.indexOf('Files') !== -1) ){ droptarget.classList.add('active'); return false; } }; droptarget.ondragleave = function () { droptarget.classList.remove('active'); }; droptarget.ondragover = function(e) { return false; }; droptarget.ondrop = function(e) { var files = e.dataTransfer.files; for(var i=0; i<files.length; i++){ var type = files[i].type; if (type.substring(0, 6) !== 'image/') { continue; } var img = document.createElement('img'); img.src = getBlobURL(files[i]); img.onload = function () { this.width = 100; document.body.append(this); revokeBlobURL(this.src); // 防止内存泄漏 } } droptarget.classList.remove('active'); return false; } } </script>
        <style> #droptarget {border: solid black 2px; width: 200px; height: 200px;} #droptarget.active {border: solid red 4px;} </style>
    </head>
    <body>
    <div id="droptarget">Drop Files Here</div>
    </body>
</html>
复制代码
  1. 经过postMessage()在窗口和工做进程间传输blob数据

  2. 将blob存储在客户端数据库

  3. 经过XMLHTTPRequest的send()方法将blob上传到服务器

5. FileReader对象的异步接口以stringArrayBuffer的形式提取blob对象的内容。

由于Blob的体积比较大,全部访问磁盘上的blob的相关API都是异步的。

function readfile(f){
    var reader = new FileReader();
    reader.readAsText(f);
    reader.onload = function () {
        var text = reader.result;
        console.log('file content: ', text);
    }
    reader.onerror = function(e){
        console.log('Error', e);
    }
}
复制代码
  1. 经过Filesystem APIFileWriter对象将Blob对象写到本地文件,相关接口浏览器暂不支持。
相关文章
相关标签/搜索