توضح هذه المقالة كيفية الاتصال ب Azure Blob Storage باستخدام مكتبة عميل Azure Blob Storage ل JavaScript. بمجرد الاتصال، تستطيع التعليمة البرمجية الخاصة بك العمل على الحاويات وميزات خدمة الكائنات الثنائية كبيرة الحجم.
بالنسبة لتطبيقات العميل (المتصفح)، تحتاج إلى أدوات التجميع.
إعداد مشروعك
افتح موجه الأوامر وقم بالتغيير إلى مجلد المشروع. تغيير YOUR-DIRECTORY إلى اسم المجلد الخاص بك:
cd YOUR-DIRECTORY
إذا لم يكن لديك ملف package.json بالفعل في الدليل، فقم بتهيئة المشروع لإنشاء الملف:
npm init -y
تثبيت TypeScript ومكتبة عميل Azure Blob Storage ل JavaScript مع تضمين أنواع TypeScript:
npm install typescript @azure/storage-blob
إذا كنت ترغب في استخدام اتصالات بدون كلمة مرور باستخدام معرف Microsoft Entra، فقم بتثبيت مكتبة عميل Azure Identity ل JavaScript:
npm install @azure/identity
تخويل الوصول والاتصال ب Blob Storage
يوفر معرف Microsoft Entra الاتصال الأكثر أمانا من خلال إدارة هوية الاتصال (الهوية المدارة). تسمح لك هذه الوظيفة بدون كلمة مرور بتطوير تطبيق لا يتطلب أي أسرار (مفاتيح أو سلسلة الاتصال) مخزنة في التعليمات البرمجية.
إعداد الوصول إلى الهوية إلى سحابة Azure
للاتصال ب Azure بدون كلمات مرور، تحتاج إلى إعداد هوية Azure أو استخدام هوية موجودة. بمجرد إعداد الهوية، تأكد من تعيين الأدوار المناسبة للهوية.
لتخويل الوصول بدون كلمة مرور باستخدام معرف Microsoft Entra، ستحتاج إلى استخدام بيانات اعتماد Azure. يعتمد نوع بيانات الاعتماد التي تحتاج لها على مكان تشغيل التطبيق. استخدم هذا الجدول كدليل.
يجب أن يكون لمورد التخزين الخاص بك دور واحد أو أكثر من أدوار Azure RBAC التالية المعينة لمورد الهوية الذي تخطط للاتصال به. قم بإعداد أدوار Azure Storage لكل هوية قمت بإنشائها في الخطوة السابقة: سحابة Azure، والتطوير المحلي، المحلي.
بعد إكمال الإعداد، تحتاج كل هوية إلى واحد على الأقل من الأدوار المناسبة:
بمجرد إعداد أدوار هوية حساب تخزين Azure والبيئة المحلية الخاصة بك، قم بإنشاء ملف TypeScript الذي يتضمن الحزمة @azure/identity . إنشاء بيانات اعتماد، مثل DefaultAzureCredential، لتنفيذ اتصالات بدون كلمة مرور إلى Blob Storage. استخدم بيانات الاعتماد هذه للمصادقة مع كائن BlobServiceClient .
// connect-with-default-azure-credential.js
// You must set up RBAC for your identity with one of the following roles:
// - Storage Blob Data Reader
// - Storage Blob Data Contributor
import { DefaultAzureCredential } from '@azure/identity';
import { BlobServiceClient } from '@azure/storage-blob';
import * as dotenv from 'dotenv';
dotenv.config();
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME as string;
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 = 'my-container';
const blobName = 'my-blob';
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
const downloadResult = await blobClient.downloadToFile(fileName);
if (downloadResult.errorCode) throw Error(downloadResult.errorCode);
console.log(
`${fileName} downloaded ${downloadResult.contentType}, isCurrentVersion: ${downloadResult.isCurrentVersion}`
);
}
main()
.then(() => console.log(`success`))
.catch((err: unknown) => {
if (err instanceof Error) {
console.log(err.message);
}
});
dotenv يتم استخدام الحزمة لقراءة اسم حساب التخزين الخاص بك من .env ملف. يجب عدم إيداع هذا الملف في عنصر تحكم المصدر. إذا كنت تستخدم كيان خدمة محلي كجزء من إعداد DefaultAzureCredential، فستنتقل أي معلومات أمان لبيانات الاعتماد هذه أيضا إلى .env الملف.
إذا كنت تخطط لنشر التطبيق على الخوادم والعملاء الذين يعملون خارج Azure، فقم بإنشاء أحد بيانات الاعتماد التي تلبي احتياجاتك.
// connect-with-account-name-and-key.js
import {
BlobServiceClient,
StorageSharedKeyCredential
} from '@azure/storage-blob';
import * as dotenv from 'dotenv';
import path from 'path';
dotenv.config();
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME as string;
const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY as string;
if (!accountName) throw Error('Azure Storage accountName not found');
if (!accountKey) throw Error('Azure Storage accountKey not found');
const sharedKeyCredential = new StorageSharedKeyCredential(
accountName,
accountKey
);
const blobServiceClient = new BlobServiceClient(
`https://${accountName}.blob.core.windows.net`,
sharedKeyCredential
);
async function main(): Promise<void> {
const containerName = 'my-container';
const blobName = 'my-blob';
const timestamp = Date.now();
const fileName = path.join(
__dirname,
'../files',
`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
const downloadResult = await blobClient.downloadToFile(fileName);
if (downloadResult.errorCode) throw Error(downloadResult.errorCode);
console.log(
`${fileName} downloaded, created on ${downloadResult.createdOn}}`
);
}
main()
.then(() => console.log(`success`))
.catch((err: unknown) => {
if (err instanceof Error) {
console.log(err.message);
}
});
dotenv يتم استخدام الحزمة لقراءة اسم حساب التخزين والمفتاح من .env ملف. يجب عدم إيداع هذا الملف في عنصر تحكم المصدر.
للحصول على معلومات حول كيفية الحصول على مفاتيح الحساب وإرشادات أفضل الممارسات لإدارة مفاتيحك وحمايتها بشكل صحيح، راجع إدارة مفاتيح الوصول إلى حساب التخزين.
هام
يجب استخدام مفتاح الوصول إلى الحساب بحذر. إذا فقدت مفتاح الوصول إلى حسابك أو تم وضعه عن طريق الخطأ في موقع غير آمن، فقد تصبح خدمتك عرضة للخطر. يمكن لأي شخص لديه مفتاح الوصول تخويل الطلبات مقابل حساب التخزين، ولديه حق الوصول إلى جميع البيانات بشكل فعال. DefaultAzureCredential يوفر ميزات وفوائد أمان محسنة وهو النهج الموصى به لإدارة التخويل لخدمات Azure.
قم بإنشاء Uri في موردك باستخدام نقطة نهاية خدمة كائن ثنائي كبير الحجم ورمز SAS المميز. ثم قم بإنشاء BlobServiceClient باستخدام Uri. رمز SAS المميز هو سلسلة من أزواج الاسم/القيمة في سلسلة الاستعلام بتنسيق مثل:
بالنسبة للسيناريوهات التي يتم فيها استخدام توقيعات الوصول المشترك (SAS)، توصي Microsoft باستخدام SAS لتفويض المستخدم. يتم تأمين SAS لتفويض المستخدم باستخدام بيانات اعتماد Microsoft Entra بدلا من مفتاح الحساب. لمعرفة المزيد، راجع إنشاء SAS لتفويض مستخدم باستخدام JavaScript.
// Azure Storage dependency
import { ContainerClient } from '@azure/storage-blob';
// Azure authentication for credential dependency
import { DefaultAzureCredential } from '@azure/identity';
// For development environment - include environment variables from .env
import * as dotenv from 'dotenv';
dotenv.config();
// Azure Storage resource name
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME as string;
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 = `my-container`;
async function main(): Promise<void> {
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({
includeMetadata: true,
includeSnapshots: false,
includeTags: true,
includeVersions: false,
prefix: ''
})) {
console.log(`Blob ${i++}: ${blob.name}`);
}
} catch (err) {
console.log(err);
throw err;
}
}
main()
.then(() => console.log(`success`))
.catch((err: unknown) => {
if (err instanceof Error) {
console.log(err.message);
}
});
// Azure Storage dependency
import {
ContainerClient,
StorageSharedKeyCredential
} from '@azure/storage-blob';
// For development environment - include environment variables from .env
import * as dotenv from 'dotenv';
dotenv.config();
// Azure Storage resource name
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME as string;
if (!accountName) throw Error('Azure Storage accountName not found');
// Azure Storage resource key
const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY as string;
if (!accountKey) throw Error('Azure Storage accountKey not found');
const sharedKeyCredential = new StorageSharedKeyCredential(
accountName,
accountKey
);
const baseUrl = `https://${accountName}.blob.core.windows.net`;
const containerName = `my-container`;
async function main(): Promise<void> {
try {
// create container from ContainerClient
const containerClient = new ContainerClient(
`${baseUrl}/${containerName}`,
sharedKeyCredential
);
// do something with containerClient...
let i = 1;
// List blobs in container
for await (const blob of containerClient.listBlobsFlat({
includeMetadata: true,
includeSnapshots: false,
includeTags: true,
includeVersions: false,
prefix: ''
})) {
console.log(`Blob ${i++}: ${blob.name}`);
}
} catch (err) {
console.log(err);
throw err;
}
}
main()
.then(() => console.log(`success`))
.catch((err: unknown) => {
if (err instanceof Error) {
console.log(err.message);
}
});
هام
يجب استخدام مفتاح الوصول إلى الحساب بحذر. إذا فقدت مفتاح الوصول إلى حسابك أو تم وضعه عن طريق الخطأ في موقع غير آمن، فقد تصبح خدمتك عرضة للخطر. يمكن لأي شخص لديه مفتاح الوصول تخويل الطلبات مقابل حساب التخزين، ولديه حق الوصول إلى جميع البيانات بشكل فعال. DefaultAzureCredential يوفر ميزات وفوائد أمان محسنة وهو النهج الموصى به لإدارة التخويل لخدمات Azure.
// Azure Storage dependency
import { ContainerClient } from '@azure/storage-blob';
// For development environment - include environment variables
import * as dotenv from 'dotenv';
dotenv.config();
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME as string;
if (!accountName) throw Error('Azure Storage accountName not found');
// Container must exist prior to running this script
const containerName = `my-container`;
// SAS token must have LIST permissions on container that haven't expired
const sasToken = process.env.AZURE_STORAGE_SAS_TOKEN as string;
// Create SAS URL
const sasUrl = `https://${accountName}.blob.core.windows.net/${containerName}?${sasToken}`;
async function main(): Promise<void> {
try {
// create container client from SAS token
const containerClient = new ContainerClient(sasUrl);
// do something with containerClient...
let i = 1;
// List blobs in container
for await (const blob of containerClient.listBlobsFlat({
includeMetadata: true,
includeSnapshots: false,
includeTags: true,
includeVersions: false,
prefix: ''
})) {
console.log(`Blob ${i++}: ${blob.name}`);
}
} catch (err) {
console.log(err);
throw err;
}
}
main()
.then(() => console.log(`success`))
.catch((err: unknown) => {
if (err instanceof Error) {
console.log(err.message);
}
});
إشعار
بالنسبة للسيناريوهات التي يتم فيها استخدام توقيعات الوصول المشترك (SAS)، توصي Microsoft باستخدام SAS لتفويض المستخدم. يتم تأمين SAS لتفويض المستخدم باستخدام بيانات اعتماد Microsoft Entra بدلا من مفتاح الحساب. لمعرفة المزيد، راجع إنشاء SAS لتفويض مستخدم باستخدام JavaScript.
dotenv يتم استخدام الحزمة لقراءة اسم حساب التخزين الخاص بك من .env ملف. يجب عدم إيداع هذا الملف في عنصر تحكم المصدر.
إنشاء كائن BlobClient
يمكنك إنشاء أي من كائنات BlobClient، المدرجة أدناه، إما من ContainerClient، أو مباشرة.
// Azure Storage dependency
import {
BlockBlobClient,
BlockBlobUploadHeaders,
BlockBlobUploadResponse
} from '@azure/storage-blob';
import { getBlockBlobClientFromDefaultAzureCredential } from './auth-get-client';
// For development environment - include environment variables from .env
import * as dotenv from 'dotenv';
dotenv.config();
// Container must exist prior to running this script
const containerName = `my-container`;
// Random blob name and contents
const timeStamp = Date.now();
const blobName = `${timeStamp}-my-blob.txt`;
const fileContentsAsString = 'Hello there.';
const blockBlobClient: BlockBlobClient =
getBlockBlobClientFromDefaultAzureCredential(containerName, blobName);
async function main(
blockBlobClient: BlockBlobClient
): Promise<BlockBlobUploadHeaders> {
// Get file url - available before contents are uploaded
console.log(`blob.url: ${blockBlobClient.url}`);
// Upload file contents
const result: BlockBlobUploadHeaders = await blockBlobClient.upload(
fileContentsAsString,
fileContentsAsString.length
);
if (result.errorCode) throw Error(result.errorCode);
// Get results
return result;
}
main(blockBlobClient)
.then((result) => {
console.log(result);
console.log(`success`);
})
.catch((err: unknown) => {
if (err instanceof Error) {
console.log(err.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
}
*/
// Azure Storage dependency
import {
BlockBlobClient,
BlockBlobUploadHeaders,
BlockBlobUploadResponse,
StorageSharedKeyCredential
} from '@azure/storage-blob';
// For development environment - include environment variables from .env
import * as dotenv from 'dotenv';
dotenv.config();
// Azure Storage resource name
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME as string;
if (!accountName) throw Error('Azure Storage accountName not found');
// Azure Storage resource key
const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY as string;
if (!accountKey) throw Error('Azure Storage accountKey not found');
// Create credential
const sharedKeyCredential: StorageSharedKeyCredential =
new StorageSharedKeyCredential(accountName, accountKey);
const baseUrl = `https://${accountName}.blob.core.windows.net`;
const containerName = `my-container`;
const blobName = `my-blob`;
const fileContentsAsString = 'Hello there.';
async function main(): Promise<void> {
try {
// create blob from BlockBlobClient
const blockBlobClient = new BlockBlobClient(
`${baseUrl}/${containerName}/${blobName}`,
sharedKeyCredential
);
// Upload data to the blob
const blockBlobUploadResponse: BlockBlobUploadHeaders =
await blockBlobClient.upload(
fileContentsAsString,
fileContentsAsString.length
);
if (blockBlobUploadResponse.errorCode)
throw Error(blockBlobUploadResponse.errorCode);
console.log(`blob ${blockBlobClient.url} created`);
} catch (err) {
console.log(err);
throw err;
}
}
main()
.then(() => console.log(`success`))
.catch((err: unknown) => {
if (err instanceof Error) {
console.log(err.message);
}
});
هام
يجب استخدام مفتاح الوصول إلى الحساب بحذر. إذا فقدت مفتاح الوصول إلى حسابك أو تم وضعه عن طريق الخطأ في موقع غير آمن، فقد تصبح خدمتك عرضة للخطر. يمكن لأي شخص لديه مفتاح الوصول تخويل الطلبات مقابل حساب التخزين، ولديه حق الوصول إلى جميع البيانات بشكل فعال. DefaultAzureCredential يوفر ميزات وفوائد أمان محسنة وهو النهج الموصى به لإدارة التخويل لخدمات Azure.
/**
* Best practice - use managed identity to avoid keys & connection strings
* managed identity is implemented with @azure/identity's DefaultAzureCredential
*
* The identity that the managed identity chain selects must have the
* correct roles applied in order to work correctly.
*
* For local development: add your personal identity on your resource group
* az role assignment create --assignee "<your-username>" \
* --role "Blob Data Contributor" \
* --resource-group "<your-resource-group-name>"
**/
//const logger = require('@azure/logger');
//logger.setLogLevel('info');
//<Snippet_Dependencies>
import {
BlobSASPermissions,
BlobSASSignatureValues,
BlobServiceClient,
BlockBlobClient,
BlockBlobUploadHeaders,
BlockBlobUploadResponse,
generateBlobSASQueryParameters,
SASProtocol,
SASQueryParameters,
ServiceGetUserDelegationKeyResponse
} from '@azure/storage-blob';
// used for local environment variables
import * as dotenv from 'dotenv';
dotenv.config();
// Get BlobServiceClient
import { getBlobServiceClientFromDefaultAzureCredential } from './auth-get-client';
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME as string;
const blobServiceClient: BlobServiceClient =
getBlobServiceClientFromDefaultAzureCredential();
//</Snippet_Dependencies>
//<Snippet_CreateBlobSas>
// Server creates User Delegation SAS Token for blob
async function createBlobSas(
blobServiceClient: BlobServiceClient,
blobName: string
): Promise<string> {
const containerName = 'my-container';
// Best practice: create time limits
const TEN_MINUTES = 10 * 60 * 1000;
const NOW = new Date();
// Best practice: set start time a little before current time to
// make sure any clock issues are avoided
const TEN_MINUTES_BEFORE_NOW = new Date(NOW.valueOf() - TEN_MINUTES);
const TEN_MINUTES_AFTER_NOW = new Date(NOW.valueOf() + TEN_MINUTES);
// Best practice: delegation key is time-limited
// When using a user delegation key, container must already exist
const userDelegationKey: ServiceGetUserDelegationKeyResponse =
await blobServiceClient.getUserDelegationKey(
TEN_MINUTES_BEFORE_NOW,
TEN_MINUTES_AFTER_NOW
);
if (userDelegationKey.errorCode) throw Error(userDelegationKey.errorCode);
// Need only create/write permission to upload file
const blobPermissionsForAnonymousUser = 'cw';
// Best practice: SAS options are time-limited
const sasOptions: BlobSASSignatureValues = {
blobName,
containerName,
permissions: BlobSASPermissions.parse(blobPermissionsForAnonymousUser),
protocol: SASProtocol.HttpsAndHttp,
startsOn: TEN_MINUTES_BEFORE_NOW,
expiresOn: TEN_MINUTES_AFTER_NOW
};
const sasQueryParameters: SASQueryParameters = generateBlobSASQueryParameters(
sasOptions,
userDelegationKey,
accountName
);
const sasToken: string = sasQueryParameters.toString();
return sasToken;
}
//</Snippet_CreateBlobSas>
//<Snippet_UploadToBlob>
// Client or another process uses SAS token to upload content to blob
async function uploadStringToBlob(
blobName: string,
sasToken,
textAsString: string
): Promise<BlockBlobUploadHeaders> {
// Get environment variables
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME as string;
const containerName = 'my-container';
// Create Url SAS token as query string with typical `?` delimiter
const sasUrl = `https://${accountName}.blob.core.windows.net/${containerName}/${blobName}?${sasToken}`;
console.log(`\nBlobUrl = ${sasUrl}\n`);
// Create blob client from SAS token url
const blockBlobClient = new BlockBlobClient(sasUrl);
// Upload string
const blockBlobUploadResponse: BlockBlobUploadHeaders =
await blockBlobClient.upload(textAsString, textAsString.length, undefined);
if (blockBlobUploadResponse.errorCode)
throw Error(blockBlobUploadResponse.errorCode);
return blockBlobUploadResponse;
}
//</Snippet_UploadToBlob>
//<Snippet_Main>
async function main(blobServiceClient: BlobServiceClient) {
// Create random blob name for text file
const blobName = `${(0 | (Math.random() * 9e6)).toString(36)}.txt`;
// Server creates SAS Token
const userDelegationSasForBlob: string = await createBlobSas(
blobServiceClient,
blobName
);
// Server hands off SAS Token & blobName to client to
// Upload content
const result: BlockBlobUploadHeaders = await uploadStringToBlob(
blobName,
userDelegationSasForBlob,
'Hello Blob World'
);
if (result.errorCode) throw Error(result.errorCode);
console.log(`\n${blobName} uploaded successfully ${result.lastModified}\n`);
}
main(blobServiceClient)
.then(() => {
console.log(`success`);
})
.catch((err: unknown) => {
if (err instanceof Error) {
console.log(err.message);
}
});
//</Snippet_Main>
إشعار
بالنسبة للسيناريوهات التي يتم فيها استخدام توقيعات الوصول المشترك (SAS)، توصي Microsoft باستخدام SAS لتفويض المستخدم. يتم تأمين SAS لتفويض المستخدم باستخدام بيانات اعتماد Microsoft Entra بدلا من مفتاح الحساب. لمعرفة المزيد، راجع إنشاء SAS لتفويض مستخدم باستخدام JavaScript.
dotenv يتم استخدام الحزمة لقراءة اسم حساب التخزين الخاص بك من .env ملف. يجب عدم إيداع هذا الملف في عنصر تحكم المصدر.
قريبًا: خلال عام 2024، سنتخلص تدريجيًا من GitHub Issues بوصفها آلية إرسال ملاحظات للمحتوى ونستبدلها بنظام ملاحظات جديد. لمزيد من المعلومات، راجع https://aka.ms/ContentUserFeedback.