經(jīng)乘扛瘢看到一些視頻的地址是blob://xxxxxxx
這種形式,比較好奇锦茁,本篇文章就是聊一些瀏覽器中Blob對象的一些內(nèi)容炫隶。
以下內(nèi)容全文轉(zhuǎn)載自:https://github.com/pfan123/code-snippet/issues/10
一直以來,JS都沒有比較好的可以直接處理二進(jìn)制的方法仑荐。而Blob的存在雕拼,允許我們可以通過JS直接操作二進(jìn)制數(shù)據(jù)。
Blob對象
一個Blob
對象表示一個不可變的, 原始數(shù)據(jù)的類似文件對象粘招。Blob表示的數(shù)據(jù)不一定是一個JavaScript原生格式啥寇。 File 接口基于Blob,繼承 blob功能并將其擴(kuò)展為支持用戶系統(tǒng)上的文件洒扎。
數(shù)據(jù)類型 Blob 對象是在HTML5中辑甜,新增了File API。
構(gòu)造Blob對象
生成Blob對象有兩種方法:一種是使用Blob構(gòu)造函數(shù)袍冷,另一種是對已有的Blob對象使用slice()
方法切出一段磷醋。
Blob構(gòu)造函數(shù)
var blob = new Blob(data[, options]))
返回一個新創(chuàng)建的 Blob 對象,其內(nèi)容由參數(shù)中給定的數(shù)組串聯(lián)組成胡诗。
Blob構(gòu)造函數(shù)接受兩個參數(shù):
參數(shù)data
是一組數(shù)據(jù)邓线,所以必須是數(shù)組,即使只有一個字符串也必須用數(shù)組裝起來.
參數(shù)options
是對這一Blob對象的配置屬性乃戈,目前也只有一個type也就是相關(guān)的MIME需要設(shè)置 type的值:
'text/csv,charset=UTF-8'
設(shè)置為csv格式褂痰,并設(shè)置編碼為UTF-8,'text/html'
設(shè)置成html格式。
注意:任何瀏覽器支持的類型都可以這么用
var blob = new Blob(['我是Blob'],{type: 'text/html'});
Blob屬性
blob.size //Blob大兄⒙恰(以字節(jié)為單位)
blob.type //Blob的MIME類型缩歪,如果是未知,則是“ ”(空字符串)
slice() 創(chuàng)建
slice()
返回一個新的Blob對象谍憔,包含了源Blob對象中指定范圍內(nèi)的數(shù)據(jù)匪蝙。
Blob.slice([start[, end[, contentType]]])
參數(shù)說明:
start
可選主籍,開始索引,可以為負(fù)數(shù),語法類似于數(shù)組的slice
方法.默認(rèn)值為0
.
end
可選,結(jié)束索引,可以為負(fù)數(shù),語法類似于數(shù)組的slice
方法.默認(rèn)值為最后一個索引.
contentType
可選 逛球,新的Blob對象的MIME類型,這個值將會成為新的Blob對象的type屬性的值,默認(rèn)為一個空字符串.
URL.createObjectURL()
URL.createObjectURL()
靜態(tài)方法會創(chuàng)建一個 DOMString千元,其中包含一個表示參數(shù)中給出的對象的URL。這個 URL 的生命周期和創(chuàng)建它的窗口中的 document
綁定颤绕。這個新的URL 對象表示指定的 File 對象或 Blob 對象幸海。
objectURL = URL.createObjectURL(blob);
使用URL.createObjectURL()
函數(shù)可以創(chuàng)建一個Blob URL,參數(shù)blob是用來創(chuàng)建URL的File對象或者Blob對象奥务,返回值格式是:blob://URL
物独。
在每次調(diào)用 createObjectURL()
方法時,都會創(chuàng)建一個新的 URL 對象氯葬,即使你已經(jīng)用相同的對象作為參數(shù)創(chuàng)建過挡篓。當(dāng)不再需要這些 URL 對象時,每個對象必須通過調(diào)用 URL.revokeObjectURL()
方法傳入創(chuàng)建的URL為參數(shù)帚称,用來釋放它官研。瀏覽器會在文檔退出的時候自動釋放它們,但是為了獲得最佳性能和內(nèi)存使用狀況闯睹,應(yīng)該在安全的時機(jī)主動釋放掉它們戏羽。
URL.revokeObjectURL()
URL.revokeObjectURL()
靜態(tài)方法用來釋放一個之前通過調(diào)用 URL.createObjectURL()
創(chuàng)建的已經(jīng)存在的 URL 對象。當(dāng)你結(jié)束使用某個 URL 對象時楼吃,應(yīng)該通過調(diào)用這個方法來讓瀏覽器知道不再需要保持這個文件的引用了蛛壳。
window.URL.revokeObjectURL(objectURL);
參數(shù): objectURL
是一個通過URL.createObjectURL()
方法創(chuàng)建的對象URL.
Blob的使用
1.使用Blob最簡單的方法就是創(chuàng)建一個URL來指向Blob:
<a download="data.txt" id="getData">下載</a>
var data= 'Hello world!';
var blob = new Blob([data], {
type: 'text/html,charset=UTF-8'
});
window.URL = window.URL || window.webkitURL;
document.querySelector("#getData").href = URL.createObjectURL(blob);
上面的代碼將Blob URL賦值給a
,點擊后提示下載文本文件data.txt
所刀,文件內(nèi)容為”Hello World”衙荐。
2.Blob 響應(yīng)
window.URL = window.URL || window.webkitURL; // Take care of vendor prefixes.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
var img = document.createElement('img');
var URL = window.URL || window.webkitURL; //兼容處理
var objectUrl = URL.createObjectURL(blob);
img.onload = function(e) {
window.URL.revokeObjectURL(img.src); // 釋放 url.
};
img.src = objectUrl;
document.body.appendChild(img);
...
}
};
xhr.send();
總結(jié)
目前,Blob對象大多是運用在浮创,處理大文件分割上傳(利用Blob中slice
方法)忧吟,處理圖片canvas跨域(避免增加crossOrigin = "Anonymous"
,生成當(dāng)前域名的url,然后 URL.revokeObjectURL()
釋放斩披,createjs有用到)溜族,以及隱藏視頻源路徑等等。
① 大文件分割上傳
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server', true);
xhr.onload = function(e) { ... };
xhr.send(blobOrFile);
}
document.querySelector('input[type="file"]').addEventListener('change', function(e) {
var blob = this.files[0];
const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes.
const SIZE = blob.size;
var start = 0;
var end = BYTES_PER_CHUNK;
while(start < SIZE) {
upload(blob.slice(start, end));
start = end;
end = start + BYTES_PER_CHUNK;
}
}, false);
})();
② 圖片跨域請求垦沉,處理跨域問題煌抒,參考 createjs ImageLoader.js
③ 隱藏視頻源路徑
var video = document.getElementById('video');
var obj_url = window.URL.createObjectURL(blob);
video.src = obj_url;
video.play()
window.URL.revokeObjectURL(obj_url);
在使用 preloadJS處理加載問題時,我們可以繞過其他方式跨域
Queue = new createjs.LoadQueue(true, '', "Anonymous");
語法LoadQueue (preferXHR, basePath, crossOrigin)
則可以達(dá)到image.crossOrigin = "Anonymous"
設(shè)置跨域的效果厕倍,這個文檔里面沒有說明寡壮,需要閱讀源碼才能知道。
④ 使用 createObjectURL(blob)
輸出頁面,移動端長按保存况既,轉(zhuǎn)發(fā)
實例發(fā)現(xiàn)这溅,經(jīng)過 revokeObjectURL(url)
將喪失長按保存轉(zhuǎn)發(fā)所有功能,不釋放兼容性不是特別好棒仍,目前ios全部支持悲靴,andriod部分機(jī)型不支持