LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

細(xì)說(shuō)Web API中的Blob

freeflydom
2023年11月27日 11:48 本文熱度 1394

在一般的Web開(kāi)發(fā)中,很少會(huì)用到Blob,但Blob可以滿足一些場(chǎng)景下的特殊需求。Blob,Binary Large Object的縮寫(xiě),代表二進(jìn)制類(lèi)型的大對(duì)象。Blob的概念在一些數(shù)據(jù)庫(kù)中有使用到,例如,MYSQL中的BLOB類(lèi)型就表示二進(jìn)制數(shù)據(jù)的容器。在Web中,Blob類(lèi)型的對(duì)象表示不可變的類(lèi)似文件對(duì)象的原始數(shù)據(jù),通俗點(diǎn)說(shuō),就是Blob對(duì)象是二進(jìn)制數(shù)據(jù),但它是類(lèi)似文件對(duì)象的二進(jìn)制數(shù)據(jù),因此可以像操作File對(duì)象一樣操作Blob對(duì)象,實(shí)際上,F(xiàn)ile繼承自Blob。

Blob基本用法

創(chuàng)建

可以通過(guò)Blob的構(gòu)造函數(shù)創(chuàng)建Blob對(duì)象:

Blob(blobParts[, options])

參數(shù)說(shuō)明:

blobParts:數(shù)組類(lèi)型,數(shù)組中的每一項(xiàng)連接起來(lái)構(gòu)成Blob對(duì)象的數(shù)據(jù),數(shù)組中的每項(xiàng)元素可以是ArrayBuffer, ArrayBufferView, Blob, DOMString

options:可選項(xiàng),字典格式類(lèi)型,可以指定如下兩個(gè)屬性:

  • type,默認(rèn)值為 "",它代表了將會(huì)被放入到blob中的數(shù)組內(nèi)容的MIME類(lèi)型。

  • endings,默認(rèn)值為"transparent",用于指定包含行結(jié)束符\n的字符串如何被寫(xiě)入。 它是以下兩個(gè)值中的一個(gè): "native",表示行結(jié)束符會(huì)被更改為適合宿主操作系統(tǒng)文件系統(tǒng)的換行符; "transparent",表示會(huì)保持blob中保存的結(jié)束符不變。

例如:

    var data1 = "a";

    var data2 = "b";

    var data3 = "<div style='color:red;'>This is a blob</div>";

    var data4 = { "name": "abc" };


    var blob1 = new Blob([data1]);

    var blob2 = new Blob([data1, data2]);

    var blob3 = new Blob([data3]);

    var blob4 = new Blob([JSON.stringify(data4)]);

    var blob5 = new Blob([data4]);

    var blob6 = new Blob([data3, data4]);


    console.log(blob1);  //輸出:Blob {size: 1, type: ""}

    console.log(blob2);  //輸出:Blob {size: 2, type: ""}

    console.log(blob3);  //輸出:Blob {size: 44, type: ""}

    console.log(blob4);  //輸出:Blob {size: 14, type: ""}

    console.log(blob5);  //輸出:Blob {size: 15, type: ""}

    console.log(blob6);  //輸出:Blob {size: 59, type: ""}

size代表Blob 對(duì)象中所包含數(shù)據(jù)的字節(jié)數(shù)。這里要注意,使用字符串和普通對(duì)象創(chuàng)建Blob時(shí)的不同,blob4使用通過(guò)JSON.stringify把data4對(duì)象轉(zhuǎn)換成json字符串,blob5則直接使用data4創(chuàng)建,兩個(gè)對(duì)象的size分別為14和15。blob4的size等于14很容易理解,因?yàn)镴SON.stringify(data4)的結(jié)果為:"{"name":"abc"}",正好14個(gè)字節(jié)(不包含最外層的引號(hào))。blob5的size等于15是如何計(jì)算而來(lái)的呢?實(shí)際上,當(dāng)使用普通對(duì)象創(chuàng)建Blob對(duì)象時(shí),相當(dāng)于調(diào)用了普通對(duì)象的toString()方法得到字符串?dāng)?shù)據(jù),然后再創(chuàng)建Blob對(duì)象。所以,blob5保存的數(shù)據(jù)是"[object Object]",是15個(gè)字節(jié)(不包含最外層的引號(hào))。

slice方法

Blob對(duì)象有一個(gè)slice方法,返回一個(gè)新的 Blob對(duì)象,包含了源 Blob對(duì)象中指定范圍內(nèi)的數(shù)據(jù)。

slice([start[, end[, contentType]]])

參數(shù)說(shuō)明:

start: 可選,代表 Blob 里的下標(biāo),表示第一個(gè)會(huì)被會(huì)被拷貝進(jìn)新的 Blob 的字節(jié)的起始位置。如果傳入的是一個(gè)負(fù)數(shù),那么這個(gè)偏移量將會(huì)從數(shù)據(jù)的末尾從后到前開(kāi)始計(jì)算。

end: 可選,代表的是 Blob 的一個(gè)下標(biāo),這個(gè)下標(biāo)-1的對(duì)應(yīng)的字節(jié)將會(huì)是被拷貝進(jìn)新的Blob 的最后一個(gè)字節(jié)。如果你傳入了一個(gè)負(fù)數(shù),那么這個(gè)偏移量將會(huì)從數(shù)據(jù)的末尾從后到前開(kāi)始計(jì)算。

contentType: 可選,給新的 Blob 賦予一個(gè)新的文檔類(lèi)型。這將會(huì)把它的 type 屬性設(shè)為被傳入的值。它的默認(rèn)值是一個(gè)空的字符串。

例如:

    var data = "abcdef";

    var blob1 = new Blob([data]);

    var blob2 = blob1.slice(0,3);

    

    console.log(blob1);  //輸出:Blob {size: 6, type: ""}

    console.log(blob2);  //輸出:Blob {size: 3, type: ""}

通過(guò)slice方法,從blob1中創(chuàng)建出一個(gè)新的blob對(duì)象,size等于3。

Blob使用場(chǎng)景

分片上傳

前面已經(jīng)說(shuō)過(guò),F(xiàn)ile繼承自Blob,因此我們可以調(diào)用slice方法對(duì)大文件進(jìn)行分片長(zhǎng)傳。代碼如下:

function uploadFile(file) {

  var chunkSize = 1024 * 1024;   // 每片1M大小

  var totalSize = file.size;

  var chunkQuantity = Math.ceil(totalSize/chunkSize);  //分片總數(shù)

  var offset = 0;  // 偏移量

  

  var reader = new FileReader();

  reader.onload = function(e) {

    var xhr = new XMLHttpRequest();

    xhr.open("POST","http://xxxx/upload?fileName="+file.name);

    xhr.overrideMimeType("application/octet-stream");

    

    xhr.onreadystatechange = function() {

      if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {

        ++offset;

        if(offset === chunkQuantity) {

          alert("上傳完成");

        } else if(offset === chunkQuantity-1){

          blob = file.slice(offset*chunkSize, totalSize);   // 上傳最后一片

          reader.readAsBinaryString(blob);

        } else {

          blob = file.slice(offset*chunkSize, (offset+1)*chunkSize); 

          reader.readAsBinaryString(blob);

        }

      }else {

        alert("上傳出錯(cuò)");

      }

    }

    

    if(xhr.sendAsBinary) {

      xhr.sendAsBinary(e.target.result);   // e.target.result是此次讀取的分片二進(jìn)制數(shù)據(jù)

    } else {

      xhr.send(e.target.result);

    }

  }

   var blob = file.slice(0, chunkSize);

   reader.readAsBinaryString(blob);

}

這段代碼還可以進(jìn)一步豐富,比如顯示當(dāng)前的上傳進(jìn)度,使用多個(gè)XMLHttpRequest對(duì)象并行上傳對(duì)象(需要傳遞分片數(shù)據(jù)的位置參數(shù)給服務(wù)器端)等。

Blob URL

Blob URL是blob協(xié)議的URL,它的格式如下:

blob:http://XXX

Blob URL可以通過(guò)URL.createObjectURL(blob)創(chuàng)建。在絕大部分場(chǎng)景下,我們可以像使用Http協(xié)議的URL一樣,使用Blob URL。常見(jiàn)的場(chǎng)景有:作為文件的下載地址和作為圖片資源地址。

  • 文件下載地址

<!DOCTYPE html>

<html>


<head>

    <meta charset="UTF-8">

    <title>Blob Test</title>

    <script>

        function createDownloadFile() {

            var content = "Blob Data";

            var blob = new Blob([content]);

            var link = document.getElementsByTagName("a")[0];

            link.download = "file";

            link.href = URL.createObjectURL(blob);

        }

        window.onload = createDownloadFile;

    </script>

</head>


<body>

    <a>下載</a>

</body>


</html>

點(diǎn)擊下載按鈕,瀏覽器將會(huì)下載一個(gè)名為file的文件,文件的內(nèi)容是:Blob Data。通過(guò)Blob對(duì)象,我們?cè)谇岸舜a中就可以動(dòng)態(tài)生成文件,提供給瀏覽器下載。打開(kāi)Chrome瀏覽器調(diào)試窗口,在Elements標(biāo)簽下可以看到生成的Blob URL為:



  • 圖片資源地址

為圖片文件創(chuàng)建一個(gè)Blob URL,賦值給標(biāo)簽:

<!DOCTYPE html>

<html>


<head>

    <meta charset="UTF-8">

    <title>Blob Test</title>

    <script>

        function handleFile(e) {

            var file = e.files[0];

            var blob = URL.createObjectURL(file);

            var img = document.getElementsByTagName("img")[0];

            img.src = blob;

            img.onload = function(e) {

                URL.revokeObjectURL(this.src);  // 釋放createObjectURL創(chuàng)建的對(duì)象##

            }

        }

    </script>

</head>


<body>

    <input type="file" accept="image/*" onchange="handleFile(this)" />

    <br/>

    <img style="width:200px;height:200px">

</body>


</html>

input中選擇的圖片會(huì)在里顯示出來(lái),如圖所示:



同時(shí),可以在Network標(biāo)簽欄,發(fā)現(xiàn)這個(gè)Blob URL的請(qǐng)求信息:



這個(gè)請(qǐng)求信息和平時(shí)我們使用的Http URL獲取圖片幾乎完全一樣。我們還可以使用Data URL加載圖片資源:

<!DOCTYPE html>

<html>


<head>

    <meta charset="UTF-8">

    <title>Blob Test</title>

    <script>

        function handleFile(e) {

            var file = e.files[0];

            var fileReader = new FileReader();

            var img = document.getElementsByTagName("img")[0];

            fileReader.onload = function(e) {

                img.src = e.target.result;

            }

            fileReader.readAsDataURL(file);

        }

    </script>

</head>


<body>

    <input type="file" accept="image/*" onchange="handleFile(this)" />

    <br/>

    <img style="width:200px;height:200px">

</body>


</html>

FileReader的readAsDataURL生成一個(gè)Data URL,如圖所示:



Data URL對(duì)大家來(lái)說(shuō)應(yīng)該并不陌生,Web性能優(yōu)化中有一項(xiàng)措施:把小圖片用base64編碼直接嵌入到HTML文件中,實(shí)際上就是利用了Data URL來(lái)獲取嵌入的圖片數(shù)據(jù)。

那么Blob URL和Data URL有什么區(qū)別呢?

  1. Blob URL的長(zhǎng)度一般比較短,但Data URL因?yàn)橹苯哟鎯?chǔ)圖片base64編碼后的數(shù)據(jù),往往很長(zhǎng),如上圖所示,瀏覽器在顯示Data URL時(shí)使用了省略號(hào)(…)。當(dāng)顯式大圖片時(shí),使用Blob URL能獲取更好的可能性。

  2. Blob URL可以方便的使用XMLHttpRequest獲取源數(shù)據(jù),例如:

var blobUrl = URL.createObjectURL(new Blob(['Test'], {type: 'text/plain'}));

var x = new XMLHttpRequest();

// 如果設(shè)置x.responseType = 'blob',將返回一個(gè)Blob對(duì)象,而不是文本:

// x.responseType = 'blob';

x.onload = function() {

    alert(x.responseText);   // 輸出 Test

};

x.open('get', blobUrl);

x.send();

對(duì)于Data URL,并不是所有瀏覽器都支持通過(guò)XMLHttpRequest獲取源數(shù)據(jù)的。 3. Blob URL 只能在當(dāng)前應(yīng)用內(nèi)部使用,把Blob URL復(fù)制到瀏覽器的地址欄中,是無(wú)法獲取數(shù)據(jù)的。Data URL相比之下,就有很好的移植性,你可以在任意瀏覽器中使用。

除了可以用作圖片資源的網(wǎng)絡(luò)地址,Blob URL也可以用作其他資源的網(wǎng)絡(luò)地址,例如html文件、json文件等,為了保證瀏覽器能正確的解析Blob URL返回的文件類(lèi)型,需要在創(chuàng)建Blob對(duì)象時(shí)指定相應(yīng)的type:

// 創(chuàng)建HTML文件的Blob URL

var data = "<div style='color:red;'>This is a blob</div>";

var blob = new Blob([data], { type: 'text/html' });

var blobURL = URL.createObjectURL(blob);


// 創(chuàng)建JSON文件的Blob URL

var data = { "name": "abc" };

var blob = new Blob([JSON.stringify(data)], { type: 'application/json' });

var blobURL = URL.createObjectURL(blob);


作者:艾特老干部
鏈接:https://juejin.cn/post/6844903503727427598
來(lái)源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。



該文章在 2023/11/27 11:48:05 編輯過(guò)
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
亚洲欧美v不卡在线 | 中文字字幕在线中文字在线看 | 尤物国产在线一区视频 | 亚洲bt欧美bt中文字幕 | 亚洲国产欧美日韩另类 | 可以免费观看的AV在线片 |