開始使用 Azure Blob 儲存體和 JavaScript

本文說明如何使用適用於 JavaScript 的 Azure Blob 儲存體用戶端程式庫 v12 來連線至 Azure Blob 儲存體。 連線之後,您的程式碼就可以在 Blob 儲存體服務的容器、Blob 和功能上運作。

範例程式碼片段可在 GitHub 中以可執行的 Node.js 檔案形式來取得。

API 參考 | 套件 (npm) | 程式庫原始程式碼 | 範例 | 提供意見反應

必要條件

設定您的專案

  1. 開啟命令提示字元,並變更至您的專案資料夾。 將 YOUR-DIRECTORY 變更為您的資料夾名稱:

    cd YOUR-DIRECTORY
    
  2. 如果您的目錄中還沒有 package.json 檔案,請初始化該專案以建立檔案:

    npm init -y
    
  3. 安裝適用於 JavaScript 的 Azure Blob 儲存體用戶端程式庫:

    npm install @azure/storage-blob
    
  4. 如果您想要透過 Microsoft Entra ID 使用無密碼連線,請安裝適用於 JavaScript 的 Azure 身分識別用戶端程式庫:

    npm install @azure/identity
    

授權存取 Blob 儲存體並對其進行連線

Microsoft Entra ID 藉由管理連線身分識別 (受控識別) 提供最安全的連線。 此無密碼功能可讓您開發不需要在程式碼中儲存任何秘密 (金鑰或連接字串) 的應用程式。

設定向 Azure 雲端的身分識別存取

若要在沒有密碼的情況下連線至 Azure,您必須設定 Azure 身分識別或使用現有的身分識別。 設定身分識別之後,請務必將適當的角色指派至身分識別。

若要使用 Microsoft Entra ID 授權無密碼存取,您必須使用 Azure 認證。 您需要的認證類型取決於應用程式的執行位置。 請使用下表作為指南。

Environment 方法
開發人員環境 Visual Studio Code
開發人員環境 服務主體
Azure 裝載的應用程式 Azure 裝載的應用程式設定
內部部署 內部部署應用程式設定

設定儲存體帳戶角色

您的儲存體資源必須將一或多個下列 Azure RBAC 角色指派至您規劃要與其連線的身分識別資源。 為您在上一個步驟中建立的每個身分識別設定 Azure 儲存體角色:Azure 雲端、本機開發、內部部署。

完成設定之後,每個身分識別至少需要其中一個適當的角色:

  • 資料存取角色 - 例如:

    • 儲存體 Blob 資料讀者
    • 儲存體 Blob 資料參與者
  • 資源角色 - 例如:

    • 讀取者
    • 參與者

建置您的 應用程式

組建應用程式時,程式碼主要與三種資源互動:

  • 儲存體帳戶,Azure 儲存體資料的唯一最上層命名空間。
  • 容器,組織儲存體帳戶中的 Blob 資料。
  • Blob,儲存非結構化資料,例如文字和二進位資料。

下圖顯示資源之間的關係。

Diagram of Blob storage architecture

每種資源類型都會以一或多個相關聯的 JavaScript 用戶端來表示:

類別 描述
BlobServiceClient 代表儲存體帳戶的 Blob 儲存體端點。
ContainerClient 可讓您操作 Azure 儲存體容器及其 Blob。
BlobClient 可讓您操作 Azure 儲存體 Blob。

建立 BlobServiceClient 物件

BlobServiceClient 物件是 SDK 中的最上層物件。 此用戶端可讓您操作服務、容器和 Blob。

設定 Azure 儲存體帳戶身分識別角色和本機環境之後,請建立包含 @azure/identity 套件的 JavaScript 檔案。 建立例如 DefaultAzureCredential 等認證,以實作對 Blob 儲存體的無密碼連線。 使用該認證向 BlobServiceClient 物件進行驗證。

// connect-with-default-azure-credential.js
const { BlobServiceClient } = require('@azure/storage-blob');
const { DefaultAzureCredential } = require('@azure/identity');
require('dotenv').config()

const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
if (!accountName) throw Error('Azure Storage accountName not found');

const blobServiceClient = new BlobServiceClient(
  `https://${accountName}.blob.core.windows.net`,
  new DefaultAzureCredential()
);

async function main(){
  
  const containerName = 'REPLACE-WITH-EXISTING-CONTAINER-NAME';
  const blobName = 'REPLACE-WITH-EXISTING-BLOB-NAME';

  const timestamp = Date.now();
  const fileName = `my-new-file-${timestamp}.txt`;

  // create container client
  const containerClient = await blobServiceClient.getContainerClient(containerName);

  // create blob client
  const blobClient = await containerClient.getBlockBlobClient(blobName);

  // download file
  await blobClient.downloadToFile(fileName);

  console.log(`${fileName} downloaded`);
  
}

main()
  .then(() => console.log(`done`))
  .catch((ex) => console.log(`error: ${ex.message}`));

dotenv 套件可用來從 .env 檔案讀取您的儲存體帳戶名稱。 此檔案不應簽入原始檔控制。 如果您使用本機服務主體作為 DefaultAzureCredential 設定的一部分,則該認證的任何安全性資訊也會進入 .env 檔案中。

如果您打算將應用程式部署至執行於 Azure 外部的伺服器和用戶端,請建立符合您需求的認證之一。

建立 ContainerClient 物件

您可以從 BlobServiceClient 或直接建立 ContainerClient 物件。

從 BlobServiceClient 建立 ContainerClient 物件

從 BlobServiceClient 建立 ContainerClient 物件。

// Azure Storage dependency
const {
  StorageSharedKeyCredential,
  BlobServiceClient,
} = require("@azure/storage-blob");

// For development environment - include environment variables from .env
require("dotenv").config();

// Azure Storage resource name
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
if (!accountName) throw Error("Azure Storage accountName not found");

// Azure Storage resource key
const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY;
if (!accountKey) throw Error("Azure Storage accountKey not found");

// Create credential
const sharedKeyCredential = new StorageSharedKeyCredential(
  accountName,
  accountKey
);

const baseUrl = `https://${accountName}.blob.core.windows.net`;
const containerName = `my-container`;

// Create BlobServiceClient
const blobServiceClient = new BlobServiceClient(
  `${baseUrl}`,
  sharedKeyCredential
);

async function main() {
  try {
    // Create container client
    const containerClient = await blobServiceClient.getContainerClient(
      containerName
    );

    // do something with containerClient...
    let i = 1;

    // List blobs in container
    for await (const blob of containerClient.listBlobsFlat()) {
      console.log(`Blob ${i++}: ${blob.name}`);
    }
  } catch (err) {
    console.log(err);
    throw err;
  }
}

main()
  .then(() => console.log(`done`))
  .catch((ex) => console.log(ex.message));

直接建立 ContainerClient

// Azure Storage dependency
const {
  ContainerClient
} = require("@azure/storage-blob");

// Azure authentication for credential dependency
const { DefaultAzureCredential } = require('@azure/identity');

// For development environment - include environment variables from .env
require("dotenv").config();

// Azure Storage resource name
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
if (!accountName) throw Error("Azure Storage accountName not found");

// Azure SDK needs base URL
const baseUrl = `https://${accountName}.blob.core.windows.net`;

// Unique container name
const timeStamp = Date.now();
const containerName = `test`;

async function main() {
  try {
    
    // create container client from DefaultAzureCredential
    const containerClient = new ContainerClient(
      `${baseUrl}/${containerName}`,
      new DefaultAzureCredential()
    );    

    // do something with containerClient...
    let i = 1;

    // List blobs in container
    for await (const blob of containerClient.listBlobsFlat()) {
        console.log(`Blob ${i++}: ${blob.name}`);
    }


  } catch (err) {
    console.log(err);
    throw err;
  }
}

main()
  .then(() => console.log(`done`))
  .catch((ex) => console.log(ex.message));

dotenv 套件可用來從 .env 檔案讀取您的儲存體帳戶名稱。 此檔案不應簽入原始檔控制。

建立 BlobClient 物件

您可以從 ContainerClient 或直接建立下方列出的任何 BlobClient 物件。

Blob 用戶端清單:

從 ContainerClient 建立 BlobClient 物件

// Azure Storage dependency
const {
  StorageSharedKeyCredential,
  ContainerClient
} = require("@azure/storage-blob");

// For development environment - include environment variables from .env
require("dotenv").config();

// Azure Storage resource name
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
if (!accountName) throw Error("Azure Storage accountName not found");

// Azure Storage resource key
const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY;
if (!accountKey) throw Error("Azure Storage accountKey not found");

// Create credential
const sharedKeyCredential = new StorageSharedKeyCredential(
  accountName,
  accountKey
);

const baseUrl = `https://${accountName}.blob.core.windows.net`;
const containerName = `my-container`;
const blobName = `my-blob`;

// Create ContainerClient
const containerClient = new ContainerClient(
  `${baseUrl}/${containerName}`,
  sharedKeyCredential
);  

async function main() {
  try {
  
    // Create BlobClient object
    const blobClient = containerClient.getBlobClient(blobName);

    // do something with blobClient...
    const properties = await blobClient.getProperties();
    console.log(`Blob ${blobName} properties:`);

    // get BlockBlobClient from blobClient
    const blockBlobClient = blobClient.getBlockBlobClient();

    // do something with blockBlobClient...
    const downloadResponse = await blockBlobClient.download(0);

  } catch (err) {
    console.log(err);
    throw err;
  }
}

main()
  .then(() => console.log(`done`))
  .catch((ex) => console.log(ex.message));

直接建立 BlobClient

// Azure Storage dependency
const { BlockBlobClient } = require("@azure/storage-blob");

// Azure authentication for credential dependency
const { DefaultAzureCredential } = require('@azure/identity');

// For development environment - include environment variables from .env
require("dotenv").config();

// Azure Storage resource name
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
if (!accountName) throw Error("Azure Storage accountName not found");

// Azure SDK needs base URL
const baseUrl = `https://${accountName}.blob.core.windows.net`;

// Container must exist prior to running this script
const containerName = `test`;

// Random blob name and contents
const timeStamp = Date.now();
const blobName = `${timeStamp}-my-blob.txt`;
const fileContentsAsString = "Hello there.";

async function main(){

  // Create a client that can authenticate with Azure Active Directory
  const client = new BlockBlobClient(
    `${baseUrl}/${containerName}/${blobName}`,
    new DefaultAzureCredential()
  );

  // Get file url - available before contents are uploaded
  console.log(`blob.url: ${client.url}`);

  // Upload file contents
  const result = await client.upload(fileContentsAsString, fileContentsAsString.length);

  // Get results
  return result;
}

main().then((result) => console.log(result)).catch((ex) => console.log(ex.message));

/*

Response looks like this:

{
  etag: '"0x8DAD247F1F4896E"',
  lastModified: 2022-11-29T20:26:07.000Z,
  contentMD5: <Buffer 9d 6a 29 63 87 20 77 db 67 4a 27 a3 9c 49 2e 61>,
  clientRequestId: 'a07fdd1f-5937-44c7-984f-0699a48a05c0',
  requestId: '3580e726-201e-0045-1a30-0474f6000000',
  version: '2021-04-10',
  date: 2022-11-29T20:26:06.000Z,
  isServerEncrypted: true,
  'content-length': '0',
  server: 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0',
  'x-ms-content-crc64': 'BLv7vb1ONT8=',
  body: undefined
}
*/

dotenv 套件可用來從 .env 檔案讀取您的儲存體帳戶名稱。 此檔案不應簽入原始檔控制。

另請參閱