Blob 全稱為 binary large object ,即二進(jìn)制大對(duì)象,它是 JavaScript 中的一個(gè)對(duì)象,表示原始的類似文件的數(shù)據(jù)。實(shí)際上,Blob 對(duì)象是包含有只讀原始數(shù)據(jù)的類文件對(duì)象。簡(jiǎn)單來說,Blob 對(duì)象就是一個(gè)不可修改的二進(jìn)制文件。
new Blob(array, options);
array:由 ArrayBuffer、ArrayBufferView、Blob、DOMString 等對(duì)象構(gòu)成的,將會(huì)被放進(jìn) Blob options:可選的 BlobPropertyBag 字典,它可能會(huì)指定如下兩個(gè)屬性。 type:默認(rèn)值為 "",表示將會(huì)被放入到 blob 中的數(shù)組內(nèi)容的 MIME 類型。
這里可以成為動(dòng)態(tài)文件創(chuàng)建,其正在創(chuàng)建一個(gè)類似文件的對(duì)象。這個(gè) blob 對(duì)象上有兩個(gè)屬性:
size:Blob對(duì)象中所包含數(shù)據(jù)的大小(字節(jié))
type:字符串,認(rèn)為該Blob對(duì)象所包含的 MIME 類型
下面來看打印結(jié)果:
const blob = new Blob(["Hello World"], {type: "text/plain"});
console.log(blob.size); // 11
console.log(blob.type); // "text/plain"
復(fù)制代碼
注意,字符串"Hello World"是 UTF-8 編碼的,因此它的每個(gè)字符占用 1 個(gè)字節(jié)。
到現(xiàn)在,Blob 對(duì)象看起來似乎我們還是沒有啥用。那該如何使用 Blob 對(duì)象呢?可以使用 URL.createObjectURL() 方法將其轉(zhuǎn)化為一個(gè) URL,并在 Iframe 中加載:
<iframe></iframe>
const iframe = document.getElementsByTagName("iframe")[0];
const blob = new Blob(["Hello World"], {type: "text/plain"});
iframe.src = URL.createObjectURL(blob);
其有三個(gè)參數(shù):
start:設(shè)置切片的起點(diǎn),即切片開始位置。默認(rèn)值為 0,這意味著切片應(yīng)該從第一個(gè)字節(jié)開始
end:設(shè)置切片的結(jié)束點(diǎn),會(huì)對(duì)該位置之前的數(shù)據(jù)進(jìn)行切片。默認(rèn)值為blob.size
contentType:設(shè)置新 blob 的 MIME 類型。如果省略 type,則默認(rèn)為 blob 的原始值
const iframe = document.getElementsByTagName("iframe")[0];
const blob = new Blob(["Hello World"], {type: "text/plain"});
const subBlob = blob.slice(0, 5);
iframe.src = URL.createObjectURL(subBlob);
復(fù)制代碼
此時(shí)頁面會(huì)顯示"Hello"。
文件(File)接口提供有關(guān)文件的信息,并允許網(wǎng)頁中的 JavaScript 訪問其內(nèi)容。實(shí)際上,F(xiàn)ile 對(duì)象是特殊類型的 Blob,且可以用在任意的 Blob 類型的 context 中。Blob 的屬性和方法都可以用于 File 對(duì)象。
在 JavaScript 中,主要有兩種方法來獲取 File 對(duì)象:
<input> 元素上選擇文件后返回的 FileList 對(duì)象;文件拖放操作生成的 DataTransfer 對(duì)象
<input type="file" id="fileInput" multiple="multiple">
這里給 input 標(biāo)簽添加了三個(gè)屬性:
type="file":指定 input 的輸入類型為文件
id="fileInput":指定 input 的唯一 id
multiple="multiple":指定 input 可以同時(shí)上傳多個(gè)文件
下面來給 input 標(biāo)簽添加 onchange 事件,當(dāng)選擇文件并上傳之后觸發(fā):
const fileInput = document.getElementById("fileInput");
fileInput.onchange = (e) => {
console.log(e.target.files);
}
當(dāng)點(diǎn)擊上傳文件時(shí),控制臺(tái)就會(huì)輸出一個(gè) FileList 數(shù)組,這個(gè)數(shù)組的每個(gè)元素都是一個(gè) File 對(duì)象,一個(gè)上傳的文件就對(duì)應(yīng)一個(gè) File 對(duì)象
每個(gè) File 對(duì)象都包含文件的一些屬性,這些屬性都繼承自 Blob 對(duì)象:
通常,我們?cè)谏蟼魑募r(shí),可以通過對(duì)比 size 屬性來限制文件大小,通過對(duì)比 type 來限制上傳文件的格式等。
另一種獲取 File 對(duì)象的方式就是拖放 API,這個(gè) API 很簡(jiǎn)單,就是將瀏覽器之外的文件拖到瀏覽器窗口中,并將它放在一個(gè)成為拖放區(qū)域的特殊區(qū)域中。拖放區(qū)域用于響應(yīng)放置操作并從放置的項(xiàng)目中提取信息。這些是通過 ondrop 和 ondragover 兩個(gè) API 實(shí)現(xiàn)的。
下面來看一個(gè)簡(jiǎn)單的例子,首先定義一個(gè)拖放區(qū)域:
<div id="drop-zone"></div>
然后給這個(gè)元素添加 ondragover 和 ondrop 事件處理程序:
const dropZone = document.getElementById("drop-zone");
dropZone.ondragover = (e) => {
e.preventDefault();
}
dropZone.ondrop = (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
console.log(files)
}
注意:這里給兩個(gè) API 都添加了 e.preventDefault(),用來阻止默認(rèn)事件。它是非常重要的,可以用來阻止瀏覽器的一些默認(rèn)行為,比如放置文件將顯示在瀏覽器窗口中。
當(dāng)拖放文件到拖放區(qū)域時(shí),控制臺(tái)就會(huì)輸出一個(gè) FileList 數(shù)組,該數(shù)組的每一個(gè)元素都是一個(gè) File 對(duì)象。這個(gè) FileList 數(shù)組是從事件參數(shù)的 dataTransfer 屬性的 files 獲取的
FileReader 是一個(gè)異步 API,用于讀取文件并提取其內(nèi)容以供進(jìn)一步使用。FileReader 可以將 Blob 讀取為不同的格式。
const reader = new FileReader();
FileReader 對(duì)象提供了以下方法來加載文件:
FileReader 對(duì)象常用的事件如下:
當(dāng)然,這些方法可以加上前置 on 后在HTML元素上使用,比如onload、onerror、onabort、onprogress。除此之外,由于FileReader對(duì)象繼承自EventTarget,因此還可以使用 addEventListener() 監(jiān)聽上述事件。
const fileInput = document.getElementById("fileInput");
const reader = new FileReader();
fileInput.onchange = (e) => {
reader.readAsText(e.target.files[0]);
}
reader.onload = (e) => {
console.log(e.target.result);
}
這里,首先創(chuàng)建了一個(gè) FileReader 對(duì)象,當(dāng)文件上傳成功時(shí),使用 readAsText() 方法讀取 File 對(duì)象,當(dāng)讀取操作完成時(shí)打印讀取結(jié)果。
使用上述例子讀取文本文件時(shí),就是比較正常的。如果讀取二進(jìn)制文件,比如png格式的圖片,往往會(huì)產(chǎn)生亂碼. 那該如何處理這種二進(jìn)制數(shù)據(jù)呢?readAsDataURL() 是一個(gè)不錯(cuò)的選擇,它可以將讀取的文件的內(nèi)容轉(zhuǎn)換為 base64 數(shù)據(jù)的 URL 表示。這樣,就可以直接將 URL 用在需要源鏈接的地方,比如 img 標(biāo)簽的 src 屬性。
const fileInput = document.getElementById("fileInput");
const reader = new FileReader();
fileInput.onchange = (e) => {
reader.readAsDataURL(e.target.files[0]);
}
reader.onload = (e) => {
console.log(e.target.result);
}
將上傳的圖片通過以上方式顯示在頁面上:
<input type="file" id="fileInput" />
<img id="preview" />
const fileInput = document.getElementById("fileInput");
const preview = document.getElementById("preview");
const reader = new FileReader();
fileInput.onchange = (e) => {
reader.readAsDataURL(e.target.files[0]);
};
reader.onload = (e) => {
preview.src = e.target.result;
console.log(e.target.result);
};
當(dāng)上傳大文件時(shí),可以通過 progress 事件來監(jiān)控文件的讀取進(jìn)度:
ArrayBuffer 對(duì)象用來表示通用的、固定長(zhǎng)度的原始二進(jìn)制數(shù)據(jù)緩沖區(qū)。ArrayBuffer 的內(nèi)容不能直接操作,只能通過 DataView 對(duì)象或 TypedArrray 對(duì)象來訪問。這些對(duì)象用于讀取和寫入緩沖區(qū)內(nèi)容。
ArrayBuffer 本身就是一個(gè)黑盒,不能直接讀寫所存儲(chǔ)的數(shù)據(jù),需要借助以下視圖對(duì)象來讀寫:
TypedArray視圖和 DataView視圖的區(qū)別主要是字節(jié)序,前者的數(shù)組成員都是同一個(gè)數(shù)據(jù)類型,后者的數(shù)組成員可以是不同的數(shù)據(jù)類型。
那 ArrayBuffer 與 Blob 有啥區(qū)別呢?根據(jù) ArrayBuffer 和 Blob 的特性,Blob 作為一個(gè)整體文件,適合用于傳輸;當(dāng)需要對(duì)二進(jìn)制數(shù)據(jù)進(jìn)行操作時(shí)(比如要修改某一段數(shù)據(jù)時(shí)),就可以使用 ArrayBuffer。
ArrayBuffer 有哪些常用的方法和屬性。
new ArrayBuffer(bytelength)
ArrayBuffer()構(gòu)造函數(shù)可以分配指定字節(jié)數(shù)量的緩沖區(qū),其參數(shù)和返回值如下:
const buffer = new ArrayBuffer(16);
console.log(buffer.byteLength); // 16
ArrayBuffer 實(shí)例上還有一個(gè) slice 方法,該方法可以用來截取 ArrayBuffer 實(shí)例,它返回一個(gè)新的 ArrayBuffer ,它的內(nèi)容是這個(gè) ArrayBuffer 的字節(jié)副本,從 begin(包括),到 end(不包括)。來看例子:
const buffer = new ArrayBuffer(16);
console.log(buffer.slice(0, 8)); // 16
這里會(huì)從 buffer 對(duì)象上將前8個(gè)字節(jié)生成一個(gè)新的ArrayBuffer對(duì)象。這個(gè)方法實(shí)際上有兩步操作,首先會(huì)分配一段指定長(zhǎng)度的內(nèi)存,然后拷貝原來ArrayBuffer對(duì)象的置頂部分。
ArrayBuffer 上有一個(gè) isView()方法,它的返回值是一個(gè)布爾值,如果參數(shù)是 ArrayBuffer 的視圖實(shí)例則返回 true,例如類型數(shù)組對(duì)象或 DataView 對(duì)象;否則返回 false。簡(jiǎn)單來說,這個(gè)方法就是用來判斷參數(shù)是否是 TypedArray 實(shí)例或者 DataView 實(shí)例:
const buffer = new ArrayBuffer(16);
ArrayBuffer.isView(buffer) // false
const view = new Uint32Array(buffer);
ArrayBuffer.isView(view) // true
TypedArray 對(duì)象一共提供 9 種類型的視圖,每一種視圖都是一種構(gòu)造函數(shù)
元素 | 類型化數(shù)組 | 字節(jié) | 描述 |
Int8 | Int8Array | 1 | 8 位有符號(hào)整數(shù) |
Uint8 | Uint8Array | 1 | 8 位無符號(hào)整數(shù) |
Uint8C | Uint8ClampedArray | 1 | 8 位無符號(hào)整數(shù) |
Int16 | Int16Array | 2 | 16 位有符號(hào)整數(shù) |
Uint16 | Uint16Array | 2 | 16 位無符號(hào)整數(shù) |
Int32 | Int32Array | 4 | 32 位有符號(hào)整數(shù) |
Uint32 | Uint32Array | 4 | 32 位無符號(hào)整數(shù) |
Float32 | Float32Array | 4 | 32 位浮點(diǎn) |
Float64 | Float64Array | 8 | 64 位浮點(diǎn) |
這些構(gòu)造函數(shù)生成的對(duì)象統(tǒng)稱為 TypedArray 對(duì)象。它們和正常的數(shù)組很類似,都有l(wèi)ength 屬性,都能用索引獲取數(shù)組元素,所有數(shù)組的方法都可以在類型化數(shù)組上面使用。
那類型化數(shù)組和數(shù)組有什么區(qū)別呢?
TypedArray 的語法如下(TypedArray只是一個(gè)概念,實(shí)際使用的是那9個(gè)對(duì)象):
new Int8Array(length);
new Int8Array(typedArray);
new Int8Array(object);
new Int8Array(buffer [, byteOffset [, length]]);
TypedArray(typeArray) :接收一個(gè)視圖實(shí)例作為參數(shù)
const view = new Int8Array(new Uint8Array(6));
view[0] = 10;
view[3] = 6;
console.log(view);
需要注意,TypedArray視圖會(huì)開辟一段新的內(nèi)存,不會(huì)在原數(shù)組上建立內(nèi)存。當(dāng)然,這里創(chuàng)建的類型化數(shù)組也能轉(zhuǎn)換回普通數(shù)組:
Array.prototype.slice.call(view); // [10, 2, 3, 6, 5]
每種視圖的構(gòu)造函數(shù)都有一個(gè) BYTES_PER_ELEMENT 屬性,表示這種數(shù)據(jù)類型占據(jù)的字節(jié)數(shù):
Int8Array.BYTES_PER_ELEMENT // 1
Uint8Array.BYTES_PER_ELEMENT // 1
Int16Array.BYTES_PER_ELEMENT // 2
Uint16Array.BYTES_PER_ELEMENT // 2
Int32Array.BYTES_PER_ELEMENT // 4
Uint32Array.BYTES_PER_ELEMENT // 4
Float32Array.BYTES_PER_ELEMENT // 4
Float64Array.BYTES_PER_ELEMENT // 8
BYTES_PER_ELEMENT 屬性也可以在類型化數(shù)組的實(shí)例上獲取:
const buffer = new ArrayBuffer(16);
const view = new Uint32Array(buffer);
console.log(Uint32Array.BYTES_PER_ELEMENT); // 4
說完 ArrayBuffer,下面來看看另一種操作 ArrayBuffer 的方式:DataView。DataView 視圖是一個(gè)可以從 二進(jìn)制 ArrayBuffer 對(duì)象中讀寫多種數(shù)值類型的底層接口,使用它時(shí),不用考慮不同平臺(tái)的字節(jié)序問題。
DataView視圖提供更多操作選項(xiàng),而且支持設(shè)定字節(jié)序。本來,在設(shè)計(jì)目的上,ArrayBuffer對(duì)象的各種TypedArray視圖,是用來向網(wǎng)卡、聲卡之類的本機(jī)設(shè)備傳送數(shù)據(jù),所以使用本機(jī)的字節(jié)序就可以了;而DataView視圖的設(shè)計(jì)目的,是用來處理網(wǎng)絡(luò)設(shè)備傳來的數(shù)據(jù),所以大端字節(jié)序或小端字節(jié)序是可以自行設(shè)定的。
const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);
console.log(view);
DataView實(shí)例有以下常用屬性:
DataView 實(shí)例提供了以下方法來讀取內(nèi)存,它們的參數(shù)都是一個(gè)字節(jié)序號(hào),表示開始讀取的字節(jié)位置:
const buffer = new ArrayBuffer(24);
const view = new DataView(buffer);
// 從第1個(gè)字節(jié)讀取一個(gè)8位無符號(hào)整數(shù)
const view1 = view.getUint8(0);
// 從第2個(gè)字節(jié)讀取一個(gè)16位無符號(hào)整數(shù)
const view2 = view.getUint16(1);
// 從第4個(gè)字節(jié)讀取一個(gè)16位無符號(hào)整數(shù)
const view3 = view.getUint16(3);
DataView 實(shí)例提供了以下方法來寫入內(nèi)存,它們都接受兩個(gè)參數(shù),第一個(gè)參數(shù)表示開始寫入數(shù)據(jù)的字節(jié)序號(hào),第二個(gè)參數(shù)為寫入的數(shù)據(jù):
其實(shí) Blob URL/Object URL 是一種偽協(xié)議,允許將 Blob 和 File 對(duì)象用作圖像、二進(jìn)制數(shù)據(jù)下載鏈接等的 URL 源。
對(duì)于 Blob/File 對(duì)象,可以使用 URL構(gòu)造函數(shù)的 createObjectURL() 方法創(chuàng)建將給出的對(duì)象的 URL。這個(gè) URL 對(duì)象表示指定的 File 對(duì)象或 Blob 對(duì)象。我們可以在<img>、<script> 標(biāo)簽中或者 <a> 和 <link> 標(biāo)簽的 href 屬性中使用這個(gè) URL。 :
<input type="file" id="fileInput" />
<img id="preview" />
再來使用 URL.createObjectURL() 將File 對(duì)象轉(zhuǎn)化為一個(gè) URL:
const fileInput = document.getElementById("fileInput");
const preview = document.getElementById("preview");
fileInput.onchange = (e) => {
preview.src = URL.createObjectURL(e.target.files[0]);
console.log(preview.src);
};
const objUrl = URL.createObjectURL(new File([""], "filename"));
console.log(objUrl);
URL.revokeObjectURL(objUrl);
Base64 是一種基于64個(gè)可打印字符來表示二進(jìn)制數(shù)據(jù)的表示方法。Base64 編碼普遍應(yīng)用于需要通過被設(shè)計(jì)為處理文本數(shù)據(jù)的媒介上儲(chǔ)存和傳輸二進(jìn)制數(shù)據(jù)而需要編碼該二進(jìn)制數(shù)據(jù)的場(chǎng)景。這樣是為了保證數(shù)據(jù)的完整并且不用在傳輸過程中修改這些數(shù)據(jù)。
在 JavaScript 中,有兩個(gè)函數(shù)被分別用來處理解碼和編碼 base64 字符串:
btoa("JavaScript") // 'SmF2YVNjcmlwdA=='
atob('SmF2YVNjcmlwdA==') // 'JavaScript'
那 base64 的實(shí)際應(yīng)用場(chǎng)景有哪些呢?其實(shí)多數(shù)場(chǎng)景就是基于Data URL的。比如,使用toDataURL()方法把 canvas 畫布內(nèi)容生成 base64 編碼格式的圖片:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext("2d");
const dataUrl = canvas.toDataURL();
除此之外,還可以使用readAsDataURL()方法把上傳的文件轉(zhuǎn)為base64格式的data URI,比如上傳頭像展示或者編輯:
<input type="file" id="fileInput" />
<img id="preview" />
const fileInput = document.getElementById("fileInput");
const preview = document.getElementById("preview");
const reader = new FileReader();
fileInput.onchange = (e) => {
reader.readAsDataURL(e.target.files[0]);
};
reader.onload = (e) => {
preview.src = e.target.result;
console.log(e.target.result);
};
另外,一些小的圖片都可以使用 base64 格式進(jìn)行展示,img標(biāo)簽和background的 url 屬性都支持使用base64 格式的圖片,這樣做也可以減少 HTTP 請(qǐng)求。
看完這些基本的概念,下面就來看看常用格式之間是如何轉(zhuǎn)換的。
const blob = new Blob([new Uint8Array(buffer, byteOffset, length)]);
const base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
const base64toBlob = (base64Data, contentType, sliceSize) => {
const byteCharacters = atob(base64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
function blobToArrayBuffer(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject;
reader.readAsArrayBuffer(blob);
});
}
function blobToBase64(blob) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
}
const objectUrl = URL.createObjectURL(blob);
、Blob(Binary Large Object)定義:二進(jìn)制類型的大對(duì)象數(shù)據(jù),在 JavaScript 中 Blob 對(duì)象表示不可變的原始數(shù)據(jù)。
2、語法:
var aBlob = new Blob(blobParts, options);
其中:blobParts是一個(gè)由 ArrayBuffer、Blob、DOMString 等對(duì)象構(gòu)成的數(shù)組;options是一個(gè)可選項(xiàng),由type和endings組成,type代表了被放入到 blob 中的內(nèi)容的 MIME 類型,endings用于指定包含行結(jié)束符 \n 的字符串如何被表示(native表示行結(jié)束符\n被更改為適合宿主操作系統(tǒng)的換行符,transparent會(huì)保持 blob 中保存的行結(jié)束符不變)。
定義Blob
3、Blob屬性和方法:兩個(gè)只讀屬性size和type,其中size屬性用于表示數(shù)據(jù)的大小(以字節(jié)為單位),type 屬性為MIME 類型的字符串。slice([start[, end[, contentType]]])返回一個(gè)源指定范圍內(nèi)的Blob 對(duì)象;stream()返回一個(gè)讀取 blob 內(nèi)容的ReadableStream;text()返回一個(gè) Promise 對(duì)象且包含 blob 所有內(nèi)容的 UTF-8 格式的 USVString;arrayBuffer()返回一個(gè) Promise 對(duì)象且包含 blob 所有內(nèi)容的二進(jìn)制格式的 ArrayBuffer。
Blob屬性和方法
4、Blob URL/Object URL 是一種偽協(xié)議,允許 Blob作為鏈接的URL源,如a.href、img.src等。
創(chuàng)建 Blob URL:url=URL.createObjectURL(Blob),覽器器為 URL.createObjectURL 生成的 URL 存儲(chǔ)了一個(gè) URL → Blob 映射,此類 URL 較短,例如
blob:http://domain/b3ad7623-60bb-4eff-9b9d-f925438b97c7
Blob 本身仍駐留在內(nèi)存中,在不需要時(shí),可以調(diào)用URL.revokeObjectURL(url)來刪除引用。
5、base64也可以作為<img src= />的源,格式為
data:[<mediatype>][;base64],<data>
其中mediatype 是個(gè)MIME 類型的字符串,如 image/png,默認(rèn)值為 text/plain;charset=US-ASCII,例如:
<img src="data:image/png;base64,R0lGODlheABaAPf/AAC...">
lob對(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ù)來進(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
既然是對(duì)象,那么blob也擁有自己的屬性以及方法
屬性
布爾值,指示Blob.close()是否在該對(duì)象上調(diào)用過。關(guān)閉的blob對(duì)象不可讀。
Blob對(duì)象中所包含數(shù)據(jù)的大小(字節(jié))。
一個(gè)字符串,表明該Blob對(duì)象所包含數(shù)據(jù)的MIME類型。如果類型未知,則該值為空字符串。
方法
關(guān)閉Blob對(duì)象,以便能釋放底層資源。
返回一個(gè)新的Blob對(duì)象,包含了源Blob對(duì)象中指定范圍內(nèi)的數(shù)據(jù)。其實(shí)就是對(duì)這個(gè)blob中的數(shù)據(jù)進(jìn)行切割,我們?cè)趯?duì)文件進(jìn)行分片上傳的時(shí)候需要使用到這個(gè)方法。
看到上面這些方法和屬性,使用過HTML5提供的File接口的應(yīng)該都很熟悉,這些屬性和方法在File接口中也都有。其實(shí)File接口就是基于Blob,繼承blob功能并將其擴(kuò)展為支持用戶系統(tǒng)上的文件,也就是說:
File接口中的Flie對(duì)象就是繼承與Blob對(duì)象。
blob對(duì)象的使用
上面說了很多關(guān)于Blob對(duì)象的一些概念性的東西,下面我們來看看實(shí)際用途。
分片上傳
首先說說分片上傳,我們?cè)谶M(jìn)行文件上傳的時(shí)候,因?yàn)榉?wù)器的限制,會(huì)限制每一次上傳到服務(wù)器的文件大小不會(huì)很大,這個(gè)時(shí)候我們就需要把一個(gè)需要上傳的文件進(jìn)行切割,然后分別進(jìn)行上傳到服務(wù)器。
假如需要做到這一步,我們需要解決兩個(gè)問題:
首先怎么切割的問題上面已經(jīng)有過說明,因?yàn)镕ile文件對(duì)象是繼承與Blob對(duì)象的,因此File文件對(duì)象也擁有slice這個(gè)方法,我們可以使用這個(gè)方法將任何一個(gè)File文件進(jìn)行切割。
代碼如下:
通過上面的方法。我們就得到了一個(gè)切割之后的File對(duì)象組成的數(shù)組blobs;
接下來要做的時(shí)候就是講這些文件分別上傳到服務(wù)器。
在HTTP1.1以上的協(xié)議中,有Transfer-Encoding這個(gè)編碼協(xié)議,用以和服務(wù)器通信,來得知當(dāng)前分片傳遞的文件進(jìn)程。
這樣解決了這兩個(gè)問題,我們不僅可以對(duì)文件進(jìn)行分片上傳,并且能夠得到文件上傳的進(jìn)度。
粘貼圖片
blob還有一個(gè)應(yīng)用場(chǎng)景,就是獲取剪切板上的數(shù)據(jù)來進(jìn)行粘貼的操作。例如通過QQ截圖后,需要在網(wǎng)頁上進(jìn)行粘貼操作。
粘貼圖片我們需要解決下面幾個(gè)問題
首先我們可以通過paste事件來監(jiān)聽用戶的粘貼操作:
然后通過事件對(duì)象中的clipboardData對(duì)象來獲取圖片的文件數(shù)據(jù)。
clipboardData對(duì)象介紹
介紹一下clipboardData對(duì)象,它實(shí)際上是一個(gè)DataTransfer類型的對(duì)象,DataTransfer是拖動(dòng)產(chǎn)生的一個(gè)對(duì)象,但實(shí)際上粘貼事件也是它。
clipboardData的屬性介紹
items介紹
items是一個(gè)DataTransferItemList對(duì)象,自然里面都是DataTransferItem類型的數(shù)據(jù)了。
屬性
items的DataTransferItem有兩個(gè)屬性kind和type
方法
在原型上還有一些其他方法,不過在處理剪切板操作的時(shí)候一般用不到了。
type介紹
一般types中常見的值有text/plain、text/html、Files。
有了上面這些方法,我們可以解決第二個(gè)問題即獲取到剪切板上的數(shù)據(jù)。
最后我們需要將獲取到的數(shù)據(jù)渲染到網(wǎng)頁上。
其實(shí)這個(gè)本質(zhì)上就是一個(gè)類似于上傳圖片本地瀏覽的問題。我們可以直接通過HTML5的File接口將獲取到的文件上傳到服務(wù)器然后通過講服務(wù)器返回的url地址來對(duì)圖片進(jìn)行渲染。也可以使用fileRender對(duì)象來進(jìn)行圖片本地瀏覽。
fileRender對(duì)象簡(jiǎn)介
從Blob中讀取內(nèi)容的唯一方法是使用FileReader。
FileReader接口有4個(gè)方法,其中3個(gè)用來讀取文件,另一個(gè)用來中斷讀取。無論讀取成功或失敗,方法并不會(huì)返回讀取結(jié)果,這一結(jié)果存儲(chǔ)在result屬性中。
FileReader接口包含了一套完整的事件模型,用于捕獲讀取文件時(shí)的狀態(tài)。
通過上面的方法以及事件,我們可以發(fā)現(xiàn),通過readAsDataURL方法及onload事件就可以拿到一個(gè)可本地瀏覽圖片的DataURL。
最終代碼如下:
這樣我們就可以監(jiān)聽到用戶的粘貼操作,并且將用戶粘貼的圖片文件實(shí)時(shí)的渲染到網(wǎng)頁之中了。
總結(jié)
以上是我對(duì)Blob對(duì)象的一些學(xué)習(xí)分享,希望在實(shí)際應(yīng)用上能對(duì)大家有所幫助。也希望大家多多支持小編。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。