Blob是計算機界通用術語之一,全稱寫做:BLOB(binary large object),表示二進制大對象。MySql/Oracle數據庫中,就有一種Blob類型,專門存放二進制數據。在javascript中,Blob一般表示二進制數據,不過它們不必定非得是大量數據,Blob也能夠表示一個小型文本文件的內容。本文將詳細介紹Blobjavascript
Blob(array[, options])html
Blob()構造函數返回一個新的Blob對象,blob的內容由參數數組中給出的值的串聯組成java
[注意]IE9-瀏覽器不支持數據庫
參數array是一個由ArrayBuffer、ArrayBufferView、Blob、DOMString等對象構成的Array,或者其餘相似對象的混合體,它將會被放進Blob數組
參數options是一個可選項,它可能會指定以下兩種屬性:瀏覽器
一、類型,默認值爲"",它表明了將會被放入到blob中的數組內容的MIME類型安全
二、結束符,默認值爲"transparent",它表明包含行結束符\n的字符串如何被輸出。它是如下兩個值中的一個:"native",表明行結束符會被更改成適合宿主操做系統文件系統的慣例,或者"transparent",表明會保持blob中保存的結束符不變服務器
var aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); console.log(oMyBlob);//Blob {size: 32, type: "text/html"}
Blob是不透明的,能對它們進行直接操做的就只有獲取它們的大小(以字節爲單位)、MIME類型以及將它們分割成更小的Blob異步
Blob.size(只讀):返回Blob對象中所包含數據的大小(字節)函數
Blob.type(只讀):一個字符串,代表該Blob對象所包含數據的MIME類型。若是類型未知,則該值爲空字符串
var myBlob = new Blob([1,2,3],{type:'text/plain'}); console.log(myBlob);//Blob {size: 3, type: "text/plain"} console.log(myBlob.size);//3 console.log(myBlob.type);//'text/plain'
Blob.slice([start[, end[, contentType]]])
slice()方法返回一個新的Blob對象,包含了源Blob對象中指定範圍內的數據
var subblob = blob.slice(0,1024, "text/plain");//Blob中前1KB視爲文本 var last = blob.slice(blob.size-1024, 1024);//Blob中最後1KB視爲無類型
Web瀏覽器能夠將Blob存儲到內存中或者磁盤上,Blob能夠表示很是大的數據塊(好比視頻文件),若是事先不用slice()方法將它們分割成爲小數據塊的話,沒法存儲在主內存中。正是由於Blob能夠表示很是大的數據塊,而且它可能須要磁盤的訪問權限,因此使用它們的API是異步的(在Worker線程中有提供相應的同步版本)
在使用Blob以前,首先必需要獲取Blob。其中一種方式就是把文件做爲Blob
<input type="file">元素最初是用於在HTML表單中實現文件上傳的。瀏覽器老是很當心地實現該元素,目的是爲了只容許上傳用戶顯式選擇的文件。腳本是沒法將該元素的value屬性設置成一個文件名的,這樣它們就沒法實現將用戶電腦上任意的文件進行上傳。如今,瀏覽器已經對該元素進行了擴展,容許客戶端能夠訪問用戶選擇的文件了
[注意]容許客戶端腳本讀取選擇的文件內容不會引起安全問題,它和容許這些文件上傳到服務器的安全級別是同樣的
在支持本地文件訪問的瀏覽器中,<input type="file">元素上的files屬性則是一個FileList對象。該對象是一個類數組對象,其元素要麼是0,要麼是用戶選擇的多個File對象。一個File對象就是一個Blob,除此以外,還多了name和lastModifiedDate屬性
<script> //輸出選中的文件列表相關的信息 function fileinfo(files) { for(var i = 0; i < files.length; i++) {//files是一個類數組對象 var f = files[i]; //a.txt 86 text/plain Mon Sep 19 2016 11:07:43 GMT+0800 (中國標準時間) console.log(f.name, //只是名字:沒有路徑 f.size, f.type, //size和type是Blob的屬性 f.lastModifiedDate); //修改時間 } } </script> <input type="file" onchange="fileinfo(this.files)"/>
在實際Web應用中,Blob更可能是圖片二進制形式的上傳與下載,雖然其能夠實現幾乎任意文件的二進制傳輸
第二種獲取Blob的形式是經過XHR下載Blob
var xhr = new XMLHttpRequest(); //建立一個新的XHR對象 xhr.open('GET','p5.gif'); //指定要獲取內容的URL xhr.responseType = 'blob'; //以Blob的形式 xhr.onload = function(){ //onload 比onreadystatechange更容易 //Blob {size: 944, type: "image/gif"} console.log(xhr.response); //response返回的就是Blob對象 } xhr.send(null); //發送請求
前面介紹瞭如何獲取或者建立Blob。下面來介紹如何對獲取或者建立的Blob進行操做。其中最簡單的就是能夠建立一個URL來指向該Blob。隨後,能夠以通常的URL形式在任何地方使用該URL:在D0M中、在樣式表中、甚至能夠做爲XMLHttpRequest的目標
【createObjectURL()】
使用createObjectURL()函數能夠建立一個Blob URL。URL.createObjectURL()靜態方法會建立一個DOMString,它的URL表示參數中的對象。這個URL的生命週期和建立它的窗口中的document綁定。這個新的URL對象表示着指定的File對象或者Blob對象
objectURL = URL.createObjectURL(blob);
傳遞一個Blob給createObjectURL()方法會返回一個URL(以普通字符串形式)。該URL以blob://開始,緊跟着是一小串文本字符串,該字符串用不透明的惟一標識符來標識Blob
var xhr = new XMLHttpRequest();
xhr.open('GET','test/p5.gif');
xhr.responseType = 'blob';
xhr.onload = function(){
//blob:http://127.0.0.1/539ae798-70db-44db-b216-fc932b358285
console.log(URL.createObjectURL(xhr.response));
}
xhr.send(null);
[注意]blob://URL和data://URL是不一樣的,data://URL會對內容進行編碼。blob://URL只是對瀏覽器存儲在內存中或者磁盤上的Blob的一個簡單引用
【file URL】
blob://URL和file://URL也是不一樣的,file://URL直接指向本地文件系統中的一個文件,僅暴露了文件的路徑、瀏覽目錄的許可等,除此以外任何內容都會帶來安全問題的
Blob URL和建立它們的腳本擁有一樣的源。這使得它們比file://URL更加靈活,因爲file://URL是非同源的,所以要在Web應用中使用它們相對比較麻煩。Blob://URL只有在同源的文檔中才是有效的。好比,若是將一個Blob URL經過postMessage()傳遞給一個非同源窗口,則該URL對於該窗口來講是沒有任何意義的
Blob URL並非永久有效的。一旦用戶關閉了或者離開了包含建立Blob URL腳本的文 檔,該Blob URL就失效了。好比,將Blob URL保存到本地存儲器中,而後當用戶開始一個新的Web應用會話的時再使用它,是不可能的
【URL.revokeObjectURL()】
URL.revokeObjectURL()靜態方法用來釋放一個以前經過調用URL.createObjectURL() 建立的已經存在的URL對象。當結束使用某個URL對象時,應該經過調用這個方法來讓瀏覽器知道再也不須要保持這個文件的引用了
window.URL.revokeObjectURL(objectURL);
參數objectURL是一個DOMString,表示經過調用URL.createObjectURL()方法產生的URL對象
之因此提供這樣的方式,是由於這和內存管理問題有關。一旦使用以後,Blob就再也不須要了,應當回收它。可是,若是Web瀏覽器正維護建立的Blob和Blob URL之間的映射關係,那麼即便該Blob已經不用了,也不會被回收。javascript解釋器沒法跟蹤字符串的使用狀況,若是URL仍然是有效的,那麼它只能認爲該URL可能還在用。這就意味着,在手動撤銷該URL以前,是不會將其回收的