JavaScriptでAzure BLOBストレージへデータをアップロードする

こんにちは。日山(@hiiyan0402)です。

前回に続いて、JavaScriptからAzure BLOBストレージへデータ(ブロックBLOB)をアップロードする方法をご紹介します。今回紹介するやり方は 64MBytes 以下のBLOBブロブアップロードです。それ以上のサイズのファイルはやり方が異なります。巨大サイズのファイルアップロードについては、後日ご紹介します。


下準備

BLOBのCORSを設定する

対象となるストレージアカウントに対して、ブロブアップロードのためのCORS(クロスオリジンリソース共有)を設定します。Azureストレージライブラリを使って、以下のようなプログラムを実行します。許可するHTTPメソッド(AllowedMethods)として “Put” を指定します。

static void SetCorsRule()
{
    const string connectionString = "{ ストレージアカウントの接続文字列 }";
    var account = CloudStorageAccount.Parse(connectionString);
    var client = account.CreateCloudBlobClient();

    var properties = client.GetServiceProperties();
    properties.Cors.CorsRules.Clear();
    properties.Cors.CorsRules.Add(new CorsRule()
    {
        AllowedHeaders = {"*"},
        AllowedMethods = CorsHttpMethods.Put,
        AllowedOrigins = {"*"},
        ExposedHeaders = {"*"},
        MaxAgeInSeconds = 600
    });
    client.SetServiceProperties(properties);
}

エンキューするためのSASを発行する

アカウントキーなしでBLOBをアップロードするためには、SAS(共有アクセス署名)が必要になります。
同じくAzureストレージライブラリを使って、以下のようなプログラムを実行します。

static string GenerateSas()
{
    const string connectionString = "{ ストレージアカウントの接続文字列 }";
    var account = CloudStorageAccount.Parse(connectionString);
    var client = account.CreateCloudBlobClient();
    var container = client.GetContainerReference("{ コンテナ名 }");

    return container.GetSharedAccessSignature(new SharedAccessBlobPolicy
    {
        Permissions = SharedAccessBlobPermissions.Write,
        SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-10),
        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(60),
    });
}

CloudBlobContainer クラスの GetSharedAccessSignature メソッドを呼び出すことで、SASを発行することができます。引数として、SharedAccessBlobPolicy インスタンスを指定します。このインスタンスでは、「許可する操作(Permissions)」「利用開始時刻(SharedAccessStartTime)」「利用終了時刻(SharedAccessExpiryTime)」を指定します。許可する操作として、書き込み(SharedAccessBlobPermissions.Write)を指定します。

HTMLとJavaScript

以下の通りのコードです。jQuery使用。

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
    <body>
        <input type="file" />

        http://jquery-2.1.1.min.js
        
            var account = '{ ストレージアカウント名 }';
            var container = '{ コンテナ名 }';
            var sas = '{ 発行したSAS }';

            $('input[type="file"]').change(function (e1) {
                var file = e1.target.files[0];

                var reader = new FileReader();
                reader.onloadend = function (e2) {
                    $.ajax({
                        url: 'https://'
                           + account
                           + '.blob.core.windows.net/'
                           + container + '/'
                           + file.name
                           + sas,
                        type: "PUT",
                        data: new Uint8Array(e2.target.result),
                        contentType: file.type,
                        headers: {
                            'x-ms-blob-type' : 'BlockBlob',
                        },
                        processData: false,
                    });
                }
                reader.readAsArrayBuffer(file);
            });
        
    </body>
</html>
ファイル選択フォームでファイルを指定したら、自動的にBLOBへのアップロードが行われるプログラムになります。
PUT 先の URL は、コンテナの URL + アップロードファイル名 + SAS(共有アクセス署名) になります。
JavaScript の FileAPI を使って、選択されたファイルのバイナリデータを取得します。
(reader.readAsArrayBuffer → new Uint8Array(e2.target.result) の流れ)
BLOBアップロード時に、リクエストヘッダ “x-ms-blob-type” で”BlockBlob” または “PageBlob” を指定します。これは必須です。今回はブロックBLOBをアップロードするので、”BlockBlob”を指定します。
jQuery の ajax にてPUTを行う場合、”processData” に “false” を指定する必要があります。そうしないと、アップロードデータが勝手にクエリ文字列に変換されてしまいます。

今回も最後までご覧いただきありがとうございました!

TechTarget

クラウドエンジニア  日山 雅之による記事「Microsoft Azure スマート解説」がTechTarget Japanにて好評連載中です (全7回)