1. ホーム
  2. Web制作
  3. html5

HTML5 Blobオブジェクトの使用方法

2022-01-12 12:37:34

の前に書く

本記事では、主にBlobオブジェクトのプロパティと役割についてまとめ、DEMOを通じてBlobオブジェクトの活用シーンを紹介します。

ブロブオブジェクト

JSでバイナリを直接扱うのに、これほど良い方法はありません。しかし、Blobは、JSでバイナリデータを直接操作できるようにするために存在します。

Blobオブジェクトは、読み取り専用の生データを含むファイルのようなオブジェクトです。Blobオブジェクト内のデータは、JavaScriptのネイティブフォームである必要はありません。ファイルインターフェースはBlobをベースにしており、Blobの機能を継承し、ユーザーのコンピュータ上のローカルファイルをサポートするために拡張されています。

Blobオブジェクトはバイナリデータのコンテナと考えることができ、BlobはバイナリデータのMIMEタイプを設定するために使用することもできる。

Blobの作成

コンストラクタを使用することで

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

dataArray: Blobオブジェクトに追加されるデータを含む配列。データは、ArrayBuffer、ArrayBufferView、Blob、またはDOMStringオブジェクトの任意の数であることができます。

opt: Blobオブジェクトのプロパティを設定するオブジェクト(例:MIMEタイプ)。

1. DOMStringオブジェクトをロードしたBlobオブジェクトを作成する

2、ArrayBufferオブジェクトで満たされたBlobオブジェクトを作成します。

画像

3、ArrayBufferViewオブジェクトで満たされたBlobオブジェクトを作成する(ArrayBufferViewはArrayBufferをベースに作成でき、戻り値はクラス配列である)。(以下のように、8バイトのArrayBufferを作成し、その上に各配列要素の2バイトの「ビュー」を作成します)。

Blob.slice()経由

このメソッドは、元のBlobオブジェクトの指定された範囲内のデータを含む新しいBlobオブジェクトを返します。

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

start: 開始インデックス、デフォルトは0
end: 切片終了インデックス(終了を除く)
contentType: 新しい Blob の MIME タイプ。デフォルトは空文字列。

var canvas = document.getElementById("canvas");
canvas.toBlob(function(blob){
    console.log(blob);
});

画像

アプリケーションシナリオ

前述の通り、FileインターフェースはBlobをベースに、Blobの機能を継承して拡張したものなので、FileオブジェクトをBlobと同様に使用することができます。

スライスしてアップロード

Blob.sliceメソッドを使用すると、大きなファイルをスライスし、各ファイルスライスをラウンドロビン方式でバックエンドに送信することで、ファイルを分割してアップロードすることが可能です。
/{br スライスアップロードのロジックは以下の通りです。

  • アップロードするFileオブジェクトを取得し、チャンクに従ってファイルをスライスする(スライスサイズごと)。
  • 各ファイルをpostメソッドでラウンドロビン方式でアップロードします。urlには現在アップロードされているファイルを表すクエリストリングが接続され、postボディには今回アップロードされるバイナリデータ断片が格納されます。
  • {を使用します。 インターフェースは毎回オフセットを返し、それが次のアップロードを実行するために使用されます。

以下は、分割アップロードの簡単な実装です。

initUpload();

//Initialize the upload
function initUpload() {
    var chunk = 100 * 1024; //per-chunk size
    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;
            //file slice
            for (var i = 0; i < Math.ceil(file.size / chunk); i++) {
                var end = start + chunk;
                chunks[i] = file.slice(start , end);
                start = end;
            }
            
            // Upload the file using the post method
            // The url query is spliced with the following parameters to record the upload offset
            // The post body holds the binary data to be uploaded this time
            query = {
                fileSize: file.size,
                dataSize: chunk,
                nextOffset: 0
            }

            upload(chunks, query, successPerUpload);
        }
    }
}

// Execute the upload
function upload(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");
    
    //Get the binary data in the 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);
                // interface returns nextoffset
                // resp = {
                // isFinish:false,
                // offset:100*1024
                // }
                if (typeof cb === "function") {
                    cb.call(this, resp, chunks, query)
                }
            }
        }
    }
}

// executed after each piece is uploaded successfully
function successPerUpload(resp, chunks, query) {
    if (resp.isFinish === true) {
        alert("Upload successful");
    } else {
        // not finished uploading
        query.offset = resp.offset;
        upload(chunks, query, successPerUpload);
    }
}

// Get the file binary data
function getFileBinary(file, cb) {
    var reader = new FileReader();
    reader.readAsArrayBuffer(file);
    reader.onload = function (e) {
        if (typeof cb === "function") {
            cb.call(this, this.result);
        }
    }
}

またはファイルのフロントエンドの暗号化、すべてのアップロードは、バックエンドの復号化チェックを完了しているなど、ここで繰り返さないように、より完璧にすることができます。

urlでファイルをダウンロードする

window.URLオブジェクトはBlobオブジェクトのネットワークアドレスを生成することができ、これをaタグのdownload属性と組み合わせて、urlをクリックしてファイルをダウンロードするために使用することができます。
は以下のように実装されています。

createDownload("download.txt","download file");

function createDownload(fileName, content){
    var blob = new Blob([content]);
    var link = document.createElement("a");
    link.innerHTML = fileName;
    link.download = fileName;
    link.href = URL.createObjectURL(blob);
    document.getElementsByTagName("body")[0].appendChild(link);
}

実行後、このBlobオブジェクトのアドレスがページ上に生成され、クリックすることでダウンロードできるようになります。

ダウンロード結果を見るには

画像をURLで表示する

imgのsrc属性とbackgroundのurl属性は、画像のネットワークアドレスやbase64を受け取って表示できることが分かっています。同様に、画像をBlobオブジェクトに変換して、画像を表示するためのURL(URL.createObjectURL(blob))を生成することも可能です。

概要

今回は、主にBlobオブジェクトのプロパティと利用シーンを紹介します。実際、バイナリデータを読み込むための基本オブジェクトであるBlobオブジェクトはコンテナに過ぎず、実際の業務機能はFileReaderやURL、Canvasなどで実現する必要があることがわかりますが、この後もこれらのオブジェクトの機能や利用シーンをまとめていきます。

参考

[1] MDN_Blob
[2] W3C作業草案

HTML5 Blobオブジェクトの具体的な使用方法については、この記事を紹介し、より関連するHTML5 Blobオブジェクトのコンテンツは、スクリプトハウスの過去の記事を検索するか、次の関連記事を閲覧を続けてください、私はあなたが将来的にもっとスクリプトハウスをサポートして願っています!。