JS——blob

1、【HTML5】Blob對象

(1)寫在前面:本小節主要介紹Blob對象屬性及作用,通過demo介紹blob對象的應用場景。

blob對象:一直以來,JS都沒有比較好的可以直接處理二進制的方法。而blob的存在,允許我們可以通過js直接操作二進制數據。

“一個blob對象就是一個包含有隻讀原始數據的類文件對象。blob對象中的數據並不一定得是JavaScript中的原生形式。file接口基於blob,繼承了blob的功能,並且擴展支持了用戶計算機上的本地文件”

Blob對象可以看作是存放二進制數據的容器,此外還可以通過blob設置二進制數據的MIME類型。

(2)創建blob

方法一:通過構造函數


var blob = new Blob(dataArr:Array<any>,opt:{type:string});

dataArr:數組,包含了要添加到blob對象中的數據,數據可以是任意多個ArrayBuffer,ArrayBufferView,blob或者DOMString對象

opt:對象,用於設置Blob對象的屬性(如MIME類型)

MIME:每一個 URL 都代表着一個資源對象,而當我們請求一個網頁的時候,看似只請求了一個 URI(統一資源標識符),實際上這個網頁可能包含多個 URI,例如圖片資源的 URI 和視頻資源的 URI 等。此時有些瀏覽器爲了加快訪問速度,可能會同時開多個線程去請求 URI。也就是說其實每一個 URI 都發送了一個請求報文。而當我們的瀏覽器要顯示或處理這些資源的時候,我們並不知道其響應的數據是什麼類型的,爲了區分這些資源類型,就需要用到 MIME 了。HTTP 會爲每一個通過 web 傳輸的對象添加上 MIME 類型的數據格式標籤。瀏覽器在讀取到對應的信息後,會調用相應的程序去處理它,任何得到我們想要的結果。

第一種:創建一個裝填DOMString對象的blob對象

image

第二種:創建一個裝填ArrayBuffer對象的Blob對象

image

第三種:創建一個裝填ArrayBufferView對象的Blob對象(ArrayBufferView可基於ArrayBuffer創建,返回值是一個類數組。如下,創建一個8字節的ArrayBuffer,在其上創建一個每個數組元素爲2字節的“視圖”)

image

方法二:通過Blob.slice()


此方法返回一個新的Blob對象,包含了原blob對象中指定範圍內的數據

Blob.slice(start:number,end:number,contentType:string)

start:開始索引,默認爲0

end:截止結束索引(不包括end)

contentType:新blob的MIME類型,默認爲空字符串

image

方法三:通過canvas.toBlob()


var canvas = document.getElementById("canvas");

canvas.toBlob(function(blob){

console.log(blob);

});

2、應用場景

前面提到,file接口繼承blob,繼承了blob的功能並進行了擴展,故我們可以像使用Blob一樣使用File對象

分片上傳


通過Blob.slice方法,可以將大文件分片,輪循向後臺提交各文件片段,即可實現文件的分片上傳。

分片上傳邏輯如下:

獲取要上傳文件的File對象,根據chunk(每片大小)對文件進行分片

通過post方法輪循上傳每片文件,其中url中拼接querystring用於描述當前上傳的文件信息;post body中存放本次要上傳的二進制數據片段

接口每次返回offset,用於執行下次上傳

下面是分片上傳的簡單實現:

 

initUpload();//初始化上傳functioninitUpload(){

    var chunk = 100 * 1024;  //每片大小    var input = document.getElementById("file");    //input file    input.onchange = function(e){

        var file = this.files[0];

        var query = {};

        var chunks = [];

        if (!!file) {

            var start = 0;

            //文件分片            for (var i = 0; i < Math.ceil(file.size / chunk); i++) {

                var end = start + chunk;

                chunks[i] = file.slice(start , end);

                start = end;

            }

            // 採用post方法上傳文件            // url query上拼接以下參數,用於記錄上傳偏移            // post body中存放本次要上傳的二進制數據            query = {

                fileSize: file.size,

                dataSize: chunk,

                nextOffset: 0            }

            upload(chunks, query, successPerUpload);

        }

    }

}// 執行上傳functionupload(chunks, query, cb){

    var queryStr = Object.getOwnPropertyNames(query).map(key=> {

        return key + "=" + query[key];

    }).join("&");

    var xhr = new XMLHttpRequest();

    xhr.open("POST", "http://xxxx/opload?" + queryStr);

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

    //獲取post body中二進制數據    var index = Math.floor(query.nextOffset / query.dataSize);

    getFileBinary(chunks[index], function(binary){

        if (xhr.sendAsBinary) {

            xhr.sendAsBinary(binary);

        } else {

            xhr.send(binary);

        }

    });

    xhr.onreadystatechange = function(e){

        if (xhr.readyState === 4) {

            if (xhr.status === 200) {

                var resp = JSON.parse(xhr.responseText);

                // 接口返回nextoffset                // resp = {                //    isFinish:false,                //    offset:100*1024                // }                if (typeof cb === "function") {

                    cb.call(this, resp, chunks, query)

                }

            }

        }

    }

}// 每片上傳成功後執行functionsuccessPerUpload(resp, chunks, query){

    if (resp.isFinish === true) {

        alert("上傳成功");

    } else {

        //未上傳完畢        query.offset = resp.offset;

        upload(chunks, query, successPerUpload);

    }

}// 獲取文件二進制數據functiongetFileBinary(file, cb){

    var reader = new FileReader();

    reader.readAsArrayBuffer(file);

    reader.onload = function(e){

        if (typeof cb === "function") {

            cb.call(this, this.result);

        }

    }

}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章