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對象寫到本地文件,相關接口瀏覽器暫不支持。
相關文章
相關標籤/搜索