這一系列文章都講述的是關於使用 JavaScript 操作文件相關的知識,其中最重要的是 File 對象,而實際上 file 對象只是 blob 對象的一個更具體的版本,blob 存儲着大量的二進制數據,並且 blob 的 size 和 type 屬性,都會被 file 對象所繼承。
所以,可以說,在大多數情況下,blob 對象和 file 對象可以用在同一個地方,例如,可以使用 FileReader 借口從 blob 讀取數據,也可以使用 URL.createObjectURL() 從 blob 創建一個新的 URL 對象。
Slicing (分割)
通過 Blob 對象可以做的一件有趣的事情就是可以創建一個子 Blob 對象,其實就是可以將其分割(file 對象也可以)。由於每個 Blob 對象都是通過指針指向數據的而不是指向數據本身,因此可以快速的創建指向其他子部分的新的 Blob 對象,這里就需要使用 slice() 方法了。是不是和 JavaScript 的 slice() 方法很象,其實差不多。
此方法接受三個參數,起始偏移量,結束偏移量,還有可選的 mime 類型。如果 mime 類型,沒有設置,那么新的 Blob 對象的 mime 類型和父級一樣。
不過目前瀏覽器實現此方法還沒有統一,火狐使用的是 mozSlice() ,Chrome 使用的是 webkitSlice() ,其他瀏覽器則正常的方式 slice() 。重寫的兼容各個瀏覽器的例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
function sliceBlob(blob, start, end, type) { type = type || blob.type; if (blob.mozSlice) { return blob.mozSlice(start, end, type); } else if (blob.webkitSlice) { return blob.webkitSlice(start, end type); } else { throw new Error("This doesn't work!"); } } |
當要上傳大文件的時候,此方法非常有用,可以將大文件分割分段,然后各自上傳,因為分割之后的 Blob 對象和原始的是獨立存在的。例如,Flickr 的工程師就使用此方法將照片中的需要使用的 exif 信息截取出來,而不是等到其傳到服務器上之后,才處理的,並且一旦選擇要上傳照片,則同時傳輸文件數據和 Exif 數據,這樣幾乎就可以在上傳照片的時候同時顯示照片的信息了。
使用舊方法創建 Blob 對象
當 File 對象開始出現在瀏覽器中的時候,開發者們意識到 Blob 對象太強大了,都想可以在用戶不干預的情況下,創建 Blob 對象,畢竟任何數據都可以用 Blob 對象表示,不用非要和文件產生關系。通過 BlobBuilder 創建一個包含有特定數據的 Blob 對象,然后瀏覽器快速響應即可。(不過目前其還不統一,Firefox:MozBlobBuilder, Internet Explorer 10:MSBlobBuilder,Chrome:WebKitBlobBuilder)。
例子:
1 2 3 |
var builder = new BlobBuilder(); builder.append("Hello world!"); var blob = builder.getBlob("text/plain"); |
BlobBuilder() 創建一個新實例,並且使用一個 append() 方法,將字符串(或者 ArrayBuffer 或者 Blob,此處用 string 舉例)插入,一旦數據插入成功,就可以使用 getBlob() 方法設置一個 mime 。
並且 BlobBuilder() 還可以處理動態數據,例如 worker 中的數據等,這里就不翻譯了。
使用新方法創建 Blob 對象
因為開發者一直想要能夠直接創建 Blob 對象,因此瀏覽器實現了 BlobBuilder(); Blob 作為構造函數而存在,而且,此構造函數也已經被作為標准了,其也是今后創建 Blob 對象的方式。
Blob()--構造函數,接受兩個參數,第一個為一個數據序列,可以是任意格式的值,例如,任意數量的字符串,Blobs 以及 ArrayBuffers。第二個參數,是一個包含了兩個屬性的對象,其兩個屬性分別是:
type -- MIME 的類型。
endings -- 決定 append() 的數據格式,(數據中的 \n 如何被轉換)可以取值為 "transparent" 或者 "native"(t* 的話不變,n* 的話按操作系統轉換;t* 為默認) 。
例子:
1 |
var blob = new Blob(["Hello world!"], { type: "text/plain" }); |
可以看到,此方法比 BlobBuilder() 簡單多了。
但是,此 Blob 構造函數還沒有被一些瀏覽器實現,目前只有某些版本的 Chrome 和 Firefox 實現了。而且剩余的瀏覽器也沒有確定什么時候實現,但是其現在作為 File API 的一部分,將來應該會被統一實現的。
全文完。