js中關(guān)于Blob對(duì)象的介紹與使用
blob對(duì)象介紹
一個(gè) Blob對(duì)象表示一個(gè)不可變的, 原始數(shù)據(jù)的類似文件對(duì)象。Blob表示的數(shù)據(jù)不一定是一個(gè)JavaScript原生格式 blob對(duì)象本質(zhì)上是js中的一個(gè)對(duì)象,里面可以儲(chǔ)存大量的二進(jìn)制編碼格式的數(shù)據(jù)。
創(chuàng)建blob對(duì)象
創(chuàng)建blob對(duì)象本質(zhì)上和創(chuàng)建一個(gè)其他對(duì)象的方式是一樣的,都是使用Blob() 的構(gòu)造函數(shù)來(lái)進(jìn)行創(chuàng)建。 構(gòu)造函數(shù)接受兩個(gè)參數(shù):
第一個(gè)參數(shù)為一個(gè)數(shù)據(jù)序列,可以是任意格式的值。
第二個(gè)參數(shù)是一個(gè)包含兩個(gè)屬性的對(duì)象{ type: MIME的類型, endings: 決定第一個(gè)參數(shù)的數(shù)據(jù)格式,可以取值為 "transparent" 或者 "native"(transparent的話不變,是默認(rèn)值,native 的話按操作系統(tǒng)轉(zhuǎn)換) 。 }
Blob()構(gòu)造函數(shù)允許使用其他對(duì)象創(chuàng)建一個(gè)Blob對(duì)象,比如用字符串構(gòu)建一個(gè)blob
var debug = {hello: "world"}; var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});
既然是對(duì)象,那么blob也擁有自己的屬性以及方法
屬性
- Blob.isClosed (只讀)
布爾值,指示 Blob.close() 是否在該對(duì)象上調(diào)用過(guò)。 關(guān)閉的 blob 對(duì)象不可讀。
- Blob.size (只讀)
Blob 對(duì)象中所包含數(shù)據(jù)的大?。ㄗ止?jié))。
- Blob.type (只讀)
一個(gè)字符串,表明該Blob對(duì)象所包含數(shù)據(jù)的MIME類型。如果類型未知,則該值為空字符串。
方法
- Blob.close()
關(guān)閉 Blob 對(duì)象,以便能釋放底層資源。
- Blob.slice([start[, end[, contentType]]])
返回一個(gè)新的 Blob 對(duì)象,包含了源 Blob 對(duì)象中指定范圍內(nèi)的數(shù)據(jù)。其實(shí)就是對(duì)這個(gè)blob中的數(shù)據(jù)進(jìn)行切割,我們?cè)趯?duì)文件進(jìn)行分片上傳的時(shí)候需要使用到這個(gè)方法。
看到上面這些方法和屬性,使用過(guò)HTML5提供的File接口的應(yīng)該都很熟悉,這些屬性和方法在File接口中也都有。 其實(shí)File接口就是基于Blob,繼承blob功能并將其擴(kuò)展為支持用戶系統(tǒng)上的文件,也就是說(shuō):
File接口中的Flie對(duì)象就是繼承與Blob對(duì)象。
blob對(duì)象的使用
上面說(shuō)了很多關(guān)于Blob對(duì)象的一些概念性的東西,下面我們來(lái)看看實(shí)際用途。
分片上傳
首先說(shuō)說(shuō)分片上傳,我們?cè)谶M(jìn)行文件上傳的時(shí)候,因?yàn)榉?wù)器的限制,會(huì)限制每一次上傳到服務(wù)器的文件大小不會(huì)很大,這個(gè)時(shí)候我們就需要把一個(gè)需要上傳的文件進(jìn)行切割,然后分別進(jìn)行上傳到服務(wù)器。
假如需要做到這一步,我們需要解決兩個(gè)問(wèn)題:
- 怎么切割?
- 怎么得知當(dāng)前傳輸?shù)倪M(jìn)度?
首先怎么切割的問(wèn)題上面已經(jīng)有過(guò)說(shuō)明,因?yàn)镕ile文件對(duì)象是繼承與Blob對(duì)象的,因此File文件對(duì)象也擁有slice這個(gè)方法,我們可以使用這個(gè)方法將任何一個(gè)File文件進(jìn)行切割。
代碼如下:
var BYTES_PER_CHUNK = 1024 * 1024; // 每個(gè)文件切片大小定為1MB . var blob = document.getElementById("file").files[0]; var slices = Math.ceil(blob.size / BYTES_PER_CHUNK); var blobs = []; slices.forEach(function(item, index) { blobs.push(blob.slice(index,index + 1)); });
通過(guò)上面的方法。我們就得到了一個(gè)切割之后的File對(duì)象組成的數(shù)組blobs;
接下來(lái)要做的時(shí)候就是講這些文件分別上傳到服務(wù)器。
在HTTP1.1以上的協(xié)議中,有Transfer-Encoding這個(gè)編碼協(xié)議,用以和服務(wù)器通信,來(lái)得知當(dāng)前分片傳遞的文件進(jìn)程。
這樣解決了這兩個(gè)問(wèn)題,我們不僅可以對(duì)文件進(jìn)行分片上傳,并且能夠得到文件上傳的進(jìn)度。
粘貼圖片
blob還有一個(gè)應(yīng)用場(chǎng)景,就是獲取剪切板上的數(shù)據(jù)來(lái)進(jìn)行粘貼的操作。例如通過(guò)QQ截圖后,需要在網(wǎng)頁(yè)上進(jìn)行粘貼操作。
粘貼圖片我們需要解決下面幾個(gè)問(wèn)題
- 監(jiān)聽(tīng)用戶的粘貼操作
- 獲取到剪切板上的數(shù)據(jù)
- 將獲取到的數(shù)據(jù)渲染到網(wǎng)頁(yè)中
首先我們可以通過(guò)paste事件來(lái)監(jiān)聽(tīng)用戶的粘貼操作:
document.addEventListener('paste', function (e) { console.info(e); });
然后通過(guò)事件對(duì)象中的clipboardData 對(duì)象來(lái)獲取圖片的文件數(shù)據(jù)。
clipboardData對(duì)象介紹
介紹一下 clipboardData 對(duì)象,它實(shí)際上是一個(gè) DataTransfer 類型的對(duì)象, DataTransfer 是拖動(dòng)產(chǎn)生的一個(gè)對(duì)象,但實(shí)際上粘貼事件也是它。
clipboardData 的屬性介紹
屬性 | 類型 | 說(shuō)明 |
---|---|---|
dropEffect | String | 默認(rèn)是 none |
effectAllowed | String | 默認(rèn)是 uninitialized |
files | FileList | 粘貼操作為空List |
items | DataTransferItemList | 剪切板中的各項(xiàng)數(shù)據(jù) |
types | Array | 剪切板中的數(shù)據(jù)類型 該屬性在Safari下比較混亂 |
items 介紹
items 是一個(gè) DataTransferItemList 對(duì)象,自然里面都是 DataTransferItem 類型的數(shù)據(jù)了。
屬性
items 的 DataTransferItem 有兩個(gè)屬性 kind 和 type
屬性 | 說(shuō)明 |
---|---|
kind | 一般為 string 或者 file |
type | 具體的數(shù)據(jù)類型,例如具體是哪種類型字符串或者哪種類型的文件,即 MIME-Type |
方法
方法 | 參數(shù) | 說(shuō)明 |
---|---|---|
getAsFile | 空 | 如果 kind 是 file ,可以用該方法獲取到文件 |
getAsString | function(str) | 如果 kind 是 string ,可以用該方法獲取到字符串str |
在原型上還有一些其他方法,不過(guò)在處理剪切板操作的時(shí)候一般用不到了。
type 介紹
一般 types 中常見(jiàn)的值有 text/plain 、 text/html 、 Files 。
值 | 說(shuō)明 |
---|---|
text/plain | 普通字符串 |
text/html | 帶有樣式的html |
Files | 文件(例如剪切板中的數(shù)據(jù)) |
有了上面這些方法,我們可以解決第二個(gè)問(wèn)題即獲取到剪切板上的數(shù)據(jù)。
document.addEventListener('paste', function (e) { console.info(e); var cbd = e.clipboardData; for(var i = 0; i < cbd.items.length; i++) { var item = cbd.items[i]; console.info(item); if(item.kind == "file"){ var blob = item.getAsFile(); if (blob.size === 0) { return; } console.info(blob); } } });
最后我們需要將獲取到的數(shù)據(jù)渲染到網(wǎng)頁(yè)上。
其實(shí)這個(gè)本質(zhì)上就是一個(gè)類似于上傳圖片本地瀏覽的問(wèn)題。我們可以直接通過(guò)HTML5的File接口將獲取到的文件上傳到服務(wù)器然后通過(guò)講服務(wù)器返回的url地址來(lái)對(duì)圖片進(jìn)行渲染。也可以使用fileRender對(duì)象來(lái)進(jìn)行圖片本地瀏覽。
fileRender對(duì)象簡(jiǎn)介
從Blob中讀取內(nèi)容的唯一方法是使用 FileReader。
FileReader接口有4個(gè)方法,其中3個(gè)用來(lái)讀取文件,另一個(gè)用來(lái)中斷讀取。無(wú)論讀取成功或失敗,方法并不會(huì)返回讀取結(jié)果,這一結(jié)果存儲(chǔ)在result屬性中。
方法名 | 參數(shù) | 描述 |
---|---|---|
readAsBinaryString | file | 將文件讀取為二進(jìn)制編碼 |
readAsText | file,[encoding] | 將文件讀取為文本 |
readAsDataURL | file | 將文件讀取為DataURL |
abort | (none) | 終端讀取操作 |
FileReader接口包含了一套完整的事件模型,用于捕獲讀取文件時(shí)的狀態(tài)。
事件 | 描述 |
---|---|
onabort | 中斷 |
onerror | 出錯(cuò) |
onloadstart | 開(kāi)始 |
onprogress | 正在讀取 |
onload | 成功讀取 |
onloadend | 讀取完成,無(wú)論成功失敗 |
通過(guò)上面的方法以及事件,我們可以發(fā)現(xiàn),通過(guò)readAsDataURL方法及onload事件就可以拿到一個(gè)可本地瀏覽圖片的DataURL。
最終代碼如下:
document.addEventListener('paste', function (e) { console.info(e); var cbd = e.clipboardData; var fr = new FileReader(); var html = ''; for(var i = 0; i < cbd.items.length; i++) { var item = cbd.items[i]; console.info(item); if(item.kind == "file"){ var blob = item.getAsFile(); if (blob.size === 0) { return; } console.info(blob); fr.readAsDataURL(blob); fr.on<x>load=function(e){ var result=document.getElementById("result"); //顯示文件 result.innerHTML='<img src="' + this.result +'" alt="" />'; } } } });
這樣我們就可以監(jiān)聽(tīng)到用戶的粘貼操作,并且將用戶粘貼的圖片文件實(shí)時(shí)的渲染到網(wǎng)頁(yè)之中了。
總結(jié)
以上是我對(duì)Blob對(duì)象的一些學(xué)習(xí)分享,希望在實(shí)際應(yīng)用上能對(duì)大家有所幫助。也希望大家多多支持腳本之家。
相關(guān)文章
JS字符串分割方法整理匯總示例講解(3種截取方法和6個(gè)輔助方法)
JavaScript在開(kāi)發(fā)中常常會(huì)需要截取字符串,而JS提供了slice()?、substring()、substr()?3種方法實(shí)現(xiàn)截取操作。另外還有字符串相關(guān)的6種輔助方法:indexOf()、lastIndexOf()、split()、join()、concat()、charAt()?。2023-02-02JavaScript枚舉選擇jquery插件代碼實(shí)例
這篇文章主要介紹了JavaScript枚舉選擇jquery插件代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11ztree加載完成后顯示勾選節(jié)點(diǎn)的實(shí)現(xiàn)代碼
zTree 是一個(gè)依靠 jQuery 實(shí)現(xiàn)的多功能 “樹插件”。優(yōu)異的性能、靈活的配置、多種功能的組合是 zTree 最大優(yōu)點(diǎn)。這篇文章主要介紹了ztree加載完成后顯示勾選節(jié)點(diǎn)的實(shí)現(xiàn)代碼 ,需要的朋友可以參考下2018-10-10