JavaScript中的Blob對象

經(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ā)

測試demo

實例發(fā)現(xiàn)这溅,經(jīng)過 revokeObjectURL(url) 將喪失長按保存轉(zhuǎn)發(fā)所有功能,不釋放兼容性不是特別好棒仍,目前ios全部支持悲靴,andriod部分機(jī)型不支持

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市莫其,隨后出現(xiàn)的幾起案子癞尚,更是在濱河造成了極大的恐慌,老刑警劉巖乱陡,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件否纬,死亡現(xiàn)場離奇詭異,居然都是意外死亡蛋褥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門睛驳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烙心,“玉大人,你說我怎么就攤上這事乏沸∫穑” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵蹬跃,是天一觀的道長匙瘪。 經(jīng)常有香客問我,道長蝶缀,這世上最難降的妖魔是什么丹喻? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮翁都,結(jié)果婚禮上碍论,老公的妹妹穿的比我還像新娘。我一直安慰自己柄慰,他們只是感情好鳍悠,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坐搔,像睡著了一般藏研。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上概行,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天蠢挡,我揣著相機(jī)與錄音,去河邊找鬼。 笑死袒哥,一個胖子當(dāng)著我的面吹牛缩筛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播堡称,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瞎抛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了却紧?” 一聲冷哼從身側(cè)響起桐臊,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晓殊,沒想到半個月后断凶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡巫俺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年认烁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片介汹。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡却嗡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嘹承,到底是詐尸還是另有隱情窗价,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布叹卷,位于F島的核電站撼港,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏骤竹。R本人自食惡果不足惜帝牡,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蒙揣。 院中可真熱鬧否灾,春花似錦、人聲如沸鸣奔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挎狸。三九已至扣汪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間锨匆,已是汗流浹背崭别。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工冬筒, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茅主。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓舞痰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诀姚。 傳聞我的和親對象是個殘疾皇子响牛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容