使用 Node.js V2
IBM Cloud® Object Storage ( SDK for Node.js v2 )提供了多项功能,可帮助您充分利用 IBM Cloud Object Storage。
IBM Cloud Object Storage ( SDK for Node.js v2 )功能全面,其众多特性与功能已超出本指南的范围和篇幅。 有关类和方法的详细文档,请参阅 Node.js 的 API 参考文档。 在 GitHub 存储库中可以找到源代码。
新功能 v2
IBM Cloud Object Storage ( SDK for Node.js v2 )是基于 AWS SDK( v3 )架构构建的现代化版本,带来了显著的改进:
- 模块化架构 ——仅导入您需要的命令和客户端
- 承诺优先设计 ——原生支持 async/await,并具备更简洁的错误处理机制
- 更小的打包体积 ——支持树形抖动(Tree-shaking)的模块可缩减应用程序大小
- 现代版 JavaScript ——利用 ES6+ 的功能并支持 TypeScript
- 中间件堆栈 ——可扩展的请求/响应管道
- 更完善的错误处理 ——带有详细信息的结构化错误类型
对于从 v1 迁移过来的开发者,请参阅《 迁移指南 》。
获取 SDK
安装 IBM COS SDK for Node.js 的首选方法是使用 Node.js 的 npm 包管理器。只需在终端窗口中输入以下命令即可:
npm install ibm-cos-sdk-v2
先决条件
- Node.js 18 或更高版本 ——该 SDK 要求至少使用 Node.js 18 或更高版本。
- 一个 IBM Cloud Object Storage
- 来自 IBM Cloud Identity and Access Management 且至少具有
Writer权限的API密钥 - 您正在使用的 COS 实例的 ID
- 令牌获取端点
- 服务端点
这些值可在 IBM Cloud 控制台中通过 生成“服务凭证” 找到。
导入包
安装 SDK 后,您需要将所需的包导入到 Node.js 应用程序中,才能使用该 SDK,如下例所示:
CommonJS:
const { S3Client } = require('ibm-cos-sdk-v2');
const {
CreateBucketCommand,
ListBucketsCommand,
PutObjectCommand,
GetObjectCommand
} = require('ibm-cos-sdk-v2');
ES 模块 / TypeScript:
import { S3Client } from 'ibm-cos-sdk-v2';
import {
CreateBucketCommand,
ListBucketsCommand,
PutObjectCommand,
GetObjectCommand
} from 'ibm-cos-sdk-v2';
SDK 参考资料
核心类
- S3Client- 用于交互的主要客户端 IBM Cloud Object Storage
- 命令类 ——每个操作都有一个对应的命令类(例如:
PutObjectCommand、GetObjectCommand)
配置
- S3Client 构造函数- 根据配置选项创建一个新的 S3 客户端
- region- 设置客户端的区域
- endpoint- 设置服务端点 URL
- 凭据- 设置身份验证凭据
创建客户端并获取服务凭据
为了连接到 IBM Cloud Object Storage,将通过提供凭证信息(API 密钥和服务实例标识)来创建和配置客户机。 这些值还可以自动从凭证文件或环境变量中获取。
通过创建服务凭证或通过 CLI 可以找到凭证。
使用 IBM 进行 IAM 身份验证
以下示例演示了如何使用 IBM 的IAM身份验证和API密钥创建客户端:
CommonJS:
const { S3Client } = require('ibm-cos-sdk-v2');
// Initialize client
const client = new S3Client({
endpoint: 'https://s3.us-south.cloud-object-storage.appdomain.cloud',
region: 'us-south',
credentials: {
apiKey: '<API_KEY>',
serviceInstanceId: '<SERVICE_INSTANCE_ID>'
}
});
TypeScript:
import { S3Client } from 'ibm-cos-sdk-v2';
const client = new S3Client({
endpoint: 'https://s3.us-south.cloud-object-storage.appdomain.cloud',
region: 'us-south',
credentials: {
apiKey: '<API_KEY>',
serviceInstanceId: '<SERVICE_INSTANCE_ID>'
}
});
所需的配置选项包括:
endpoint- 您所用 COS 存储桶所在区域的端点 URLregion- 您的存储桶所在的区域credentials.apiKey- 具有相应权限的 IBM Cloud API密钥credentials.serviceInstanceId- 您的 COS 实例的 CRN(云资源名称)
代码示例
以下示例假设您已经按照上一节中的说明创建了一个客户端。
创建存储区
const { CreateBucketCommand } = require('ibm-cos-sdk-v2');
const command = new CreateBucketCommand({
Bucket: 'my-new-bucket',
CreateBucketConfiguration: {
LocationConstraint: 'us-south-standard'
}
});
try {
const response = await client.send(command);
console.log('Bucket created successfully');
} catch (err) {
console.error('Error creating bucket:', err);
}
列出可用的存储桶
const { ListBucketsCommand } = require('ibm-cos-sdk-v2');
try {
const command = new ListBucketsCommand({});
const response = await client.send(command);
console.log('Buckets:');
if (response.Buckets && response.Buckets.length > 0) {
response.Buckets.forEach(bucket => {
console.log(` - ${bucket.Name} (created: ${bucket.CreationDate})`);
});
} else {
console.log(' No buckets found');
}
} catch (err) {
console.error('Failed to list buckets:', err);
}
列出包含详细信息的分类
IBM Cloud Object Storage 提供了一项扩展的列出操作,该操作会返回额外的存储桶信息:
const { ListBucketsExtendedCommand } = require('ibm-cos-sdk-v2');
const command = new ListBucketsExtendedCommand({
IBMServiceInstanceId: '<SERVICE_INSTANCE_ID>',
Prefix: 'my-bucket-prefix',
MaxKeys: 100
});
try {
const response = await client.send(command);
console.log('Extended Bucket Information:');
if (response.Buckets && response.Buckets.length > 0) {
response.Buckets.forEach(bucket => {
console.log(` Bucket: ${bucket.Name}`);
console.log(` Location: ${bucket.LocationConstraint}`);
console.log(` Created: ${bucket.CreationDate}`);
});
} else {
console.log(' No buckets found');
}
} catch (err) {
console.error('Failed to list buckets:', err);
}
获取桶的位置
const { GetBucketLocationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new GetBucketLocationCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`Bucket '${bucketName}' is located in: ${response.LocationConstraint}`);
} catch (err) {
console.error('Failed to get bucket location:', err);
}
删除存储区
const { DeleteBucketCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket-to-delete';
const command = new DeleteBucketCommand({
Bucket: bucketName
});
try {
await client.send(command);
console.log(`Bucket '${bucketName}' deleted successfully`);
} catch (err) {
console.error('Failed to delete bucket:', err);
}
注意:必须先清空存储桶,才能将其删除。
将对象上传到存储桶
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const content = 'Hello, IBM Cloud Object Storage!';
const command = new PutObjectCommand({
Bucket: bucketName,
Key: objectKey,
Body: content
});
try {
const response = await client.send(command);
console.log(`Object '${objectKey}' uploaded successfully`);
console.log(`ETag: ${response.ETag}`);
} catch (err) {
console.error('Failed to upload object:', err);
}
从存储桶中下载对象
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new GetObjectCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
// Convert stream to buffer
const chunks = [];
for await (const chunk of response.Body) {
chunks.push(chunk);
}
const buffer = Buffer.concat(chunks);
console.log(`Object '${objectKey}' downloaded successfully`);
console.log(`Content-Type: ${response.ContentType}`);
console.log(`Content-Length: ${response.ContentLength} bytes`);
console.log(`Size: ${buffer.length} bytes`);
} catch (err) {
console.error('Failed to download object:', err);
}
列出存储桶中的对象
const { ListObjectsV2Command } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListObjectsV2Command({
Bucket: bucketName,
MaxKeys: 1000
});
try {
const response = await client.send(command);
console.log(`Objects in bucket '${bucketName}':`);
if (response.Contents && response.Contents.length > 0) {
response.Contents.forEach(object => {
console.log(` - ${object.Key} (size: ${object.Size} bytes, modified: ${object.LastModified})`);
});
console.log(`\nTotal objects: ${response.Contents.length}`);
} else {
console.log(' No objects found');
}
} catch (err) {
console.error('Failed to list objects:', err);
}
复制对象
const { CopyObjectCommand } = require('ibm-cos-sdk-v2');
const sourceBucket = 'source-bucket';
const sourceKey = 'source-object.txt';
const destinationBucket = 'destination-bucket';
const destinationKey = 'destination-object.txt';
// CopySource format: source-bucket/source-key
const copySource = `${sourceBucket}/${sourceKey}`;
const command = new CopyObjectCommand({
Bucket: destinationBucket,
Key: destinationKey,
CopySource: copySource
});
try {
const response = await client.send(command);
console.log('Object copied successfully');
if (response.CopyObjectResult) {
console.log(`ETag: ${response.CopyObjectResult.ETag}`);
}
} catch (err) {
console.error('Failed to copy object:', err);
}
删除对象
const { DeleteObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'object-to-delete.txt';
const command = new DeleteObjectCommand({
Bucket: bucketName,
Key: objectKey
});
try {
await client.send(command);
console.log(`Object '${objectKey}' deleted successfully`);
} catch (err) {
console.error('Failed to delete object:', err);
}
删除多个对象
const { DeleteObjectsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectsToDelete = [
'object1.txt',
'object2.txt',
'object3.txt'
];
// Build delete request
const objects = objectsToDelete.map(key => ({ Key: key }));
const command = new DeleteObjectsCommand({
Bucket: bucketName,
Delete: {
Objects: objects,
Quiet: false
}
});
try {
const response = await client.send(command);
console.log('Delete operation completed');
if (response.Deleted && response.Deleted.length > 0) {
console.log(`Successfully deleted ${response.Deleted.length} object(s):`);
response.Deleted.forEach(deleted => {
console.log(` - ${deleted.Key}`);
});
}
if (response.Errors && response.Errors.length > 0) {
console.log(`\nFailed to delete ${response.Errors.length} object(s):`);
response.Errors.forEach(error => {
console.log(` - ${error.Key}: ${error.Message}`);
});
}
} catch (err) {
console.error('Failed to delete objects:', err);
}
获取对象元数据(HEAD)
const { HeadObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new HeadObjectCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
console.log(`Object Metadata for '${objectKey}':`);
console.log(` Content-Type: ${response.ContentType}`);
console.log(` Content-Length: ${response.ContentLength} bytes`);
console.log(` ETag: ${response.ETag}`);
console.log(` Last-Modified: ${response.LastModified}`);
if (response.Metadata && Object.keys(response.Metadata).length > 0) {
console.log(' Custom Metadata:');
for (const [key, value] of Object.entries(response.Metadata)) {
console.log(` ${key}: ${value}`);
}
}
} catch (err) {
console.error('Failed to get object metadata:', err);
}
使用分块上传
对于大型文件,分段上传不仅能提高传输速率,还支持上传中途恢复。 每个部分的大小必须至少为 5 MB(最后一个部分除外)。
手动分批上传:
const {
CreateMultipartUploadCommand,
UploadPartCommand,
CompleteMultipartUploadCommand,
AbortMultipartUploadCommand
} = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'large-object.dat';
try {
// Step 1: Initiate multipart upload
const createCommand = new CreateMultipartUploadCommand({
Bucket: bucketName,
Key: objectKey
});
const createResponse = await client.send(createCommand);
const uploadId = createResponse.UploadId;
console.log(`Multipart upload initiated with ID: ${uploadId}`);
// Step 2: Upload parts (minimum 5MB per part except last)
const completedParts = [];
const minPartSize = 5 * 1024 * 1024; // 5MB
// Create sample parts
const parts = [
'A'.repeat(minPartSize),
'B'.repeat(minPartSize)
];
for (let i = 0; i < parts.length; i++) {
const partNumber = i + 1;
const uploadPartCommand = new UploadPartCommand({
Bucket: bucketName,
Key: objectKey,
PartNumber: partNumber,
UploadId: uploadId,
Body: parts[i]
});
try {
const uploadResponse = await client.send(uploadPartCommand);
completedParts.push({
ETag: uploadResponse.ETag,
PartNumber: partNumber
});
console.log(`Part ${partNumber} uploaded (ETag: ${uploadResponse.ETag})`);
} catch (err) {
// Abort multipart upload on error
const abortCommand = new AbortMultipartUploadCommand({
Bucket: bucketName,
Key: objectKey,
UploadId: uploadId
});
await client.send(abortCommand);
throw err;
}
}
// Step 3: Complete multipart upload
const completeCommand = new CompleteMultipartUploadCommand({
Bucket: bucketName,
Key: objectKey,
UploadId: uploadId,
MultipartUpload: {
Parts: completedParts
}
});
const completeResponse = await client.send(completeCommand);
console.log('Multipart upload completed successfully');
console.log(`Location: ${completeResponse.Location}`);
console.log(`ETag: ${completeResponse.ETag}`);
} catch (err) {
console.error('Failed to complete multipart upload:', err);
}
使用上传管理器(推荐):
为了更方便地进行多部分上传,请使用 @ibm-cos/lib-storage 包:
const { Upload } = require('@ibm-cos/lib-storage');
const { S3Client } = require('ibm-cos-sdk-v2');
const fs = require('fs');
const fileStream = fs.createReadStream('large-file.bin');
const upload = new Upload({
client: client,
params: {
Bucket: 'my-bucket',
Key: 'large-file.bin',
Body: fileStream
},
queueSize: 4, // Concurrent parts
partSize: 5 * 1024 * 1024, // 5MB parts
leavePartsOnError: false
});
// Track progress
upload.on('httpUploadProgress', (progress) => {
console.log('Upload progress:', progress);
});
try {
const result = await upload.done();
console.log('Upload completed:', result);
} catch (err) {
console.error('Upload failed:', err);
}
列出多部分上传
const { ListMultipartUploadsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListMultipartUploadsCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`In-progress multipart uploads in bucket '${bucketName}':`);
if (response.Uploads && response.Uploads.length > 0) {
response.Uploads.forEach(upload => {
console.log(` Key: ${upload.Key}`);
console.log(` Upload ID: ${upload.UploadId}`);
console.log(` Initiated: ${upload.Initiated}`);
});
} else {
console.log(' No in-progress uploads found');
}
} catch (err) {
console.error('Failed to list multipart uploads:', err);
}
列出多部分上传中的各个部分
列出了正在进行的多部分上传中已上传的所有部分。 在完成上传之前,可用于检查进度或收集 ETag。
const { ListPartsCommand } = require('ibm-cos-sdk-v2');
const command = new ListPartsCommand({
Bucket: 'my-bucket',
Key: 'my-large-object',
UploadId: 'YOUR_UPLOAD_ID_HERE'
});
try {
const response = await client.send(command);
console.log('Parts listed successfully');
if (response.Parts && response.Parts.length > 0) {
response.Parts.forEach(p =>
console.log(' - Part', p.PartNumber, '| ETag:', p.ETag, '| Size:', p.Size, 'bytes')
);
} else {
console.log('No parts found.');
}
} catch (err) {
console.error('Error listing parts:', err);
}
从现有对象中复制一个部件
通过复制现有对象来上传一个部件。 当源数据已存在于 COS 中时,请使用此方法,而非上传原始字节。
const { UploadPartCopyCommand } = require('ibm-cos-sdk-v2');
const command = new UploadPartCopyCommand({
Bucket: 'my-bucket',
Key: 'my-large-object',
UploadId: 'YOUR_UPLOAD_ID_HERE',
PartNumber: 1,
CopySource: 'my-bucket/source-object-key'
});
try {
const response = await client.send(command);
console.log('Part copy uploaded successfully');
console.log('ETag:', response.CopyPartResult?.ETag);
} catch (err) {
console.error('Error uploading part copy:', err);
}
设置存储桶生命周期配置
归档策略允许您在指定时间段过后,将对象自动迁移到归档存储类:
const { PutBucketLifecycleConfigurationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
// Configure lifecycle rule to expire objects after 30 days
const command = new PutBucketLifecycleConfigurationCommand({
Bucket: bucketName,
LifecycleConfiguration: {
Rules: [
{
Id: 'delete-old-logs',
Status: 'Enabled',
Filter: {
Prefix: 'logs/',
},
Expiration: {
Days: 30,
},
},
{
Id: 'cleanup-multipart-uploads',
Status: 'Enabled',
Filter: {
Prefix: '',
},
AbortIncompleteMultipartUpload: {
DaysAfterInitiation: 7,
},
},
]
}
});
try {
await client.send(command);
console.log(`Lifecycle configuration set for bucket '${bucketName}'`);
} catch (err) {
console.error('Failed to set lifecycle configuration:', err);
}
获取存储桶的生命周期配置
const { GetBucketLifecycleConfigurationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new GetBucketLifecycleConfigurationCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`Lifecycle rules for bucket '${bucketName}':`);
if (response.Rules && response.Rules.length > 0) {
response.Rules.forEach(rule => {
console.log(` Rule ID: ${rule.ID}`);
console.log(` Status: ${rule.Status}`);
if (rule.Transitions && rule.Transitions.length > 0) {
rule.Transitions.forEach(transition => {
console.log(` Transition to ${transition.StorageClass} after ${transition.Days} days`);
});
}
});
} else {
console.log(' No lifecycle rules found');
}
} catch (err) {
console.error('Failed to get lifecycle configuration:', err);
}
启用存储桶版本控制
const { PutBucketVersioningCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new PutBucketVersioningCommand({
Bucket: bucketName,
VersioningConfiguration: {
// Valid values: 'Enabled' | 'Suspended'
Status: 'Enabled',
},
});
try {
await client.send(command);
console.log(`Versioning enabled for bucket '${bucketName}'`);
} catch (err) {
console.error('Failed to enable versioning:', err);
}
列出对象版本
const { ListObjectVersionsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListObjectVersionsCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`Object versions in bucket '${bucketName}':`);
if (response.Versions && response.Versions.length > 0) {
response.Versions.forEach(version => {
console.log(` Key: ${version.Key}`);
console.log(` Version ID: ${version.VersionId}`);
console.log(` Is Latest: ${version.IsLatest}`);
console.log(` Last Modified: ${version.LastModified}`);
});
} else {
console.log(' No versions found');
}
} catch (err) {
console.error('Failed to list object versions:', err);
}
设置 CORS 配置
const { PutBucketCorsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
// Set CORS configuration
const command = new PutBucketCorsCommand({
Bucket: bucketName,
CORSConfiguration: {
CORSRules: [
{
AllowedHeaders: ['*'],
AllowedMethods: ['GET', 'PUT', 'POST', 'DELETE'],
AllowedOrigins: ['https://example.com'],
ExposeHeaders: ['ETag'],
MaxAgeSeconds: 3000
}
]
}
});
try {
await client.send(command);
console.log(`CORS configuration set for bucket '${bucketName}'`);
} catch (err) {
console.error('Failed to set CORS configuration:', err);
}
设置对象标记
const { PutObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
// Set object tags
const command = new PutObjectTaggingCommand({
Bucket: bucketName,
Key: objectKey,
Tagging: {
TagSet: [
{
Key: 'Department',
Value: 'Finance'
},
{
Key: 'Project',
Value: 'Q4-2024'
},
{
Key: 'Classification',
Value: 'Confidential'
}
]
}
});
try {
await client.send(command);
console.log(`Tags set for object '${objectKey}'`);
} catch (err) {
console.error('Failed to set object tags:', err);
}
获取对象标签
const { GetObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new GetObjectTaggingCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
console.log(`Tags for object '${objectKey}':`);
if (response.TagSet && response.TagSet.length > 0) {
response.TagSet.forEach(tag => {
console.log(` ${tag.Key}: ${tag.Value}`);
});
} else {
console.log(' No tags found');
}
} catch (err) {
console.error('Failed to get object tags:', err);
}
还原已归档的对象
归档存储类中的对象必须先进行还原,才能被访问:
const command = new RestoreObjectCommand({
Bucket: bucketName,
Key: objectKey,
RestoreRequest: {
Days: 7,
GlacierJobParameters: {
Tier: 'Bulk',
},
},
});
try {
await client.send(command);
console.log('Object restore initiated successfully');
console.log(
'Retrieval time depends on storage class: Vault typically 1-5 hours, Cold Vault typically 5-12 hours.'
);
} catch (err) {
console.error('Failed to restore object:', err);
}
注意:IBM Cloud Object Storage 仅支持“Bulk”检索层,用于从 Vault 和 Cold Vault 存储类中恢复对象。
设置对象保留策略
管理模式:拥有特定 IAM 权限的用户可在保留期内删除对象版本。
合规模式:在保留期内,任何用户均无法删除对象版本。
const { PutObjectRetentionCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-protected-bucket';
const objectKey = 'important-document.pdf';
// Set retention until a specific date
const retainUntil = new Date();
retainUntil.setDate(retainUntil.getDate() + 30);
const command = new PutObjectRetentionCommand({
Bucket: bucketName,
Key: objectKey,
Retention: {
Mode: 'COMPLIANCE',
RetainUntilDate: retainUntil,
},
});
try {
await client.send(command);
console.log('Object retention set successfully');
console.log('RetainUntil:', retainUntil.toISOString());
} catch (err) {
console.error('Error:', err.message);
}
获取对象保留时间
const { GetObjectRetentionCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-protected-bucket';
const objectKey = 'important-document.pdf';
const command = new GetObjectRetentionCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
console.log('Object retention retrieved successfully');
console.log('Mode:', response.Retention?.Mode);
console.log('RetainUntilDate:', response.Retention?.RetainUntilDate);
} catch (err) {
console.error('Error:', err.message);
}
创建一个带有对象锁定的存储桶( S3 )
S3 对象锁定可在固定期限内或无限期地防止对象被删除或覆盖。 对象锁定必须在创建存储桶时启用——无法将其添加到现有存储桶中。
管理模式:拥有特定 IAM 权限的用户可在保留期内删除对象版本。
合规模式:在保留期内,任何用户均无法删除对象版本。
本节介绍 S3-compatible 的Object Lock功能。 有关 IBM 中 COS 特定的 WORM 保护功能,请参阅 “设置存储桶保护(WORM)”和 “管理法律保留”。
const {
CreateBucketCommand,
PutObjectLockConfigurationCommand
} = require('ibm-cos-sdk-v2');
// Step 1: Create bucket with Object Lock enabled
const createCommand = new CreateBucketCommand({
Bucket: 'my-locked-bucket',
ObjectLockEnabledForBucket: true
});
try {
await client.send(createCommand);
console.log('Bucket created with Object Lock enabled');
} catch (err) {
console.error('Error creating bucket:', err.message);
}
// Step 2: Set default retention rule
const lockConfigCommand = new PutObjectLockConfigurationCommand({
Bucket: 'my-locked-bucket',
ObjectLockConfiguration: {
ObjectLockEnabled: 'Enabled',
Rule: {
DefaultRetention: {
Mode: 'GOVERNANCE',
Days: 30
}
}
}
});
try {
await client.send(lockConfigCommand);
console.log('Default Object Lock configuration set successfully');
} catch (err) {
console.error('Error setting lock config:', err.message);
}
设置“对象锁定”配置
设置或更新适用于上传到存储桶的每个新对象的默认保留规则。
const { PutObjectLockConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectLockConfigurationCommand({
Bucket: 'my-object-lock-bucket',
ObjectLockConfiguration: {
ObjectLockEnabled: 'Enabled',
Rule: {
DefaultRetention: {
Mode: 'COMPLIANCE',
Days: 2
}
}
}
});
try {
await client.send(command);
console.log('Object lock configuration set successfully');
} catch (err) {
console.error('Error:', err.message);
}
获取对象锁配置
const { GetObjectLockConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectLockConfigurationCommand({
Bucket: 'my-object-lock-bucket'
});
try {
const response = await client.send(command);
console.log('Object lock configuration retrieved successfully');
console.log('ObjectLockEnabled:', response.ObjectLockConfiguration?.ObjectLockEnabled);
console.log('Rule:', JSON.stringify(response.ObjectLockConfiguration?.Rule, null, 2));
} catch (err) {
console.error('Error:', err.message);
}
设置 S3 对象锁定法律保留
对对象设置或解除法律保留。 在法律保留令生效期间,无论该对象的保留期限如何,均不得将其删除。
const { PutObjectLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectLegalHoldCommand({
Bucket: 'my-locked-bucket',
Key: 'my-file.txt',
LegalHold: {
Status: 'ON' // 'ON' or 'OFF'
}
});
try {
await client.send(command);
console.log('Legal hold set successfully');
} catch (err) {
console.error('Error:', err.message);
}
获取 S3 对象锁定法律保留令
const { GetObjectLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectLegalHoldCommand({
Bucket: 'my-locked-bucket',
Key: 'my-file.txt'
});
try {
const response = await client.send(command);
console.log('Legal hold retrieved successfully');
console.log('Status:', response.LegalHold?.Status);
} catch (err) {
console.error('Error:', err.message);
}
检查存储桶是否存在(HEAD)
const { HeadBucketCommand } = require('ibm-cos-sdk-v2');
const command = new HeadBucketCommand({
Bucket: 'my-bucket'
});
try {
await client.send(command);
console.log('Bucket exists');
} catch (err) {
if (err.name === 'NotFound') {
console.log('Bucket does not exist');
} else {
console.error('Error checking bucket:', err);
}
}
从文件进行流式上传
const fs = require('fs');
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const fileStream = fs.createReadStream('large-file.bin');
const command = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'large-file.bin',
Body: fileStream
});
try {
const response = await client.send(command);
console.log('File uploaded successfully');
} catch (err) {
console.error('Error uploading file:', err);
}
将流媒体内容下载到文件中
const fs = require('fs');
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'large-file.bin'
});
try {
const response = await client.send(command);
const fileStream = fs.createWriteStream('downloaded-file.bin');
response.Body.pipe(fileStream);
await new Promise((resolve, reject) => {
fileStream.on('finish', resolve);
fileStream.on('error', reject);
response.Body.on('error', reject);
});
console.log('File downloaded successfully');
} catch (err) {
console.error('Error downloading file:', err);
}
带分页功能地列出所有对象
v2 SDK 为返回截断结果的操作提供了内置的分页器。
使用分页器(推荐):
const { paginateListObjectsV2 } = require('ibm-cos-sdk-v2');
async function listAllObjects(bucket, prefix) {
const allObjects = [];
const paginator = paginateListObjectsV2(
{ client: client, pageSize: 1000 },
{ Bucket: bucket, Prefix: prefix }
);
try {
for await (const page of paginator) {
if (page.Contents) {
allObjects.push(...page.Contents);
}
}
console.log('Total objects:', allObjects.length);
return allObjects;
} catch (err) {
console.error('Error listing objects:', err);
throw err;
}
}
手动分页:
const { ListObjectsV2Command } = require('ibm-cos-sdk-v2');
async function listAllObjects(bucket, prefix) {
const allObjects = [];
let continuationToken = undefined;
do {
const command = new ListObjectsV2Command({
Bucket: bucket,
Prefix: prefix,
ContinuationToken: continuationToken
});
const response = await client.send(command);
if (response.Contents) {
allObjects.push(...response.Contents);
}
continuationToken = response.NextContinuationToken;
} while (continuationToken);
console.log('Total objects:', allObjects.length);
return allObjects;
}
生成预签名的URL
预签名 URL 允许临时、无需身份验证地访问对象。 首先安装 presigner 软件包:
npm install @ibm-cos/s3-request-presigner
预签名的 GET URL (下载):
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const { getSignedUrl } = require('@ibm-cos/s3-request-presigner');
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
console.log('Presigned URL:', url);
} catch (err) {
console.error('Error generating presigned URL:', err);
}
预签名的 PUT URL (上传):
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const { getSignedUrl } = require('@ibm-cos/s3-request-presigner');
const command = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'upload-object.txt',
ContentType: 'text/plain'
});
try {
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
console.log('Presigned PUT URL:', url);
} catch (err) {
console.error('Error generating presigned URL:', err);
}
获取 CORS 的配置
const { GetBucketCorsCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketCorsCommand({
Bucket: 'my-bucket'
});
try {
const response = await client.send(command);
console.log('CORS rules:', response.CORSRules);
} catch (err) {
console.error('Error getting CORS configuration:', err);
}
删除 CORS 配置
const { DeleteBucketCorsCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketCorsCommand({
Bucket: 'my-bucket'
});
try {
await client.send(command);
console.log('Bucket CORS configuration deleted successfully');
} catch (err) {
console.error('Error deleting CORS:', err);
}
上传带有自定义元数据的对象
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt',
Body: 'content',
Metadata: {
'author': 'John Doe',
'department': 'Engineering'
}
});
try {
await client.send(command);
console.log('Object uploaded with metadata');
} catch (err) {
console.error('Error uploading object:', err);
}
设置桶标签
const { PutBucketTaggingCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketTaggingCommand({
Bucket: 'my-bucket',
Tagging: {
TagSet: [
{ Key: 'Environment', Value: 'Production' },
{ Key: 'Project', Value: 'WebApp' }
]
}
});
try {
await client.send(command);
console.log('Bucket tags updated');
} catch (err) {
console.error('Error updating bucket tags:', err);
}
删除存储桶的生命周期配置
const { DeleteBucketLifecycleCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketLifecycleCommand({
Bucket: 'my-bucket'
});
try {
await client.send(command);
console.log('Lifecycle configuration deleted successfully');
} catch (err) {
console.error('Error deleting lifecycle:', err);
}
设置桶访问控制列表 (ACL)
const { PutBucketAclCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketAclCommand({
Bucket: 'my-bucket',
ACL: 'public-read'
});
try {
await client.send(command);
console.log('Bucket ACL updated');
} catch (err) {
console.error('Error updating bucket ACL:', err);
}
获取桶访问控制列表 (ACL)
const { GetBucketAclCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketAclCommand({
Bucket: 'my-bucket'
});
try {
const response = await client.send(command);
console.log('Bucket ACL retrieved successfully');
console.log('Owner:', response.Owner);
console.log('Grants:', response.Grants);
} catch (err) {
console.error('Error getting bucket ACL:', err);
}
设置对象访问控制列表 (ACL)
const { PutObjectAclCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectAclCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt',
ACL: 'public-read'
});
try {
await client.send(command);
console.log('Object ACL updated');
} catch (err) {
console.error('Error updating object ACL:', err);
}
获取对象访问控制列表 (ACL)
const { GetObjectAclCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectAclCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
const response = await client.send(command);
console.log('Object ACL retrieved successfully');
console.log('Owner:', response.Owner);
console.log('Grants:', response.Grants);
} catch (err) {
console.error('Error getting object ACL:', err);
}
获取版本控制状态
const { GetBucketVersioningCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketVersioningCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Bucket versioning configuration retrieved successfully');
console.log('Status:', response.Status);
// MFADelete is always undefined for IBM COS.
console.log('MFADelete:', response.MFADelete);
} catch (err) {
console.error('Error:', err.message);
}
获取特定对象的版本
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'my-file.txt',
VersionId: '<VERSION_ID>'
});
try {
const response = await client.send(command);
console.log('Version ID:', response.VersionId);
// Stream response.Body to a file or buffer as needed.
} catch (err) {
console.error('Error:', err.message);
}
将对象上传到带版本控制的存储桶
启用版本控制后,每次调用 PutObjectCommand 都会创建一个新版本。 该响应包含新的 VersionId。
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectCommand({
Bucket: 'my-versioned-bucket',
Key: 'my-file.txt',
Body: 'Hello, World!'
});
try {
const response = await client.send(command);
console.log('Object uploaded successfully');
console.log('Version ID:', response.VersionId);
} catch (err) {
console.error('Error:', err.message);
}
删除特定的对象版本
通过包含其 VersionId,永久删除该对象的一个特定版本。 如果版本化存储桶中没有版本 ID,则会创建一个删除标记。
const { DeleteObjectCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteObjectCommand({
Bucket: 'my-versioned-bucket',
Key: 'my-file.txt',
VersionId: 'YOUR_VERSION_ID_HERE'
});
try {
const response = await client.send(command);
console.log('Object version deleted successfully');
console.log('Deleted Version ID:', response.VersionId);
console.log('Delete Marker:', response.DeleteMarker ? 'Yes' : 'No');
} catch (err) {
console.error('Error:', err.message);
}
设置桶级保护(WORM)
IBM Cloud Object Storage 支持“一次写入、多次读取”(WORM)存储桶保护功能,以满足合规性和数据保留要求。
设置桶保护:
const { PutBucketProtectionConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketProtectionConfigurationCommand({
Bucket: 'my-protected-bucket',
ProtectionConfiguration: {
Status: 'Retention',
MinimumRetention: { Days: 1 },
DefaultRetention: { Days: 30 },
MaximumRetention: { Days: 365 },
},
});
try {
await client.send(command);
console.log('Bucket protection configuration set successfully');
} catch (err) {
console.error('Error configuring protection:', err.message);
}
获取桶保护:
const { GetBucketProtectionConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketProtectionConfigurationCommand({
Bucket: 'my-protected-bucket'
});
try {
const response = await client.send(command);
console.log('Bucket protection configuration retrieved successfully');
console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
console.error('Error getting protection config:', err);
}
管理法律保留令
法律保留令会阻止对象被删除,无论保留期限是否已到期。 每个锁定都由一个唯一的 ID 标识,在删除对象之前,必须显式地解除所有锁定。
注意:法律保留要求存储桶已设置“IBM”COS保护配置。
添加法律保留:
const { AddLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new AddLegalHoldCommand({
Bucket: 'my-protected-bucket',
Key: 'important-document.pdf',
RetentionLegalHoldId: 'legal-case-12345'
});
try {
await client.send(command);
console.log('Legal hold added');
} catch (err) {
console.error('Error adding legal hold:', err);
}
列出法律保留要求:
const { ListLegalHoldsCommand } = require('ibm-cos-sdk-v2');
const command = new ListLegalHoldsCommand({
Bucket: 'my-protected-bucket',
Key: 'important-document.pdf'
});
try {
const response = await client.send(command);
console.log('Legal holds listed successfully');
console.log('Legal holds:', JSON.stringify(response.LegalHolds, null, 2));
} catch (err) {
console.error('Error listing legal holds:', err);
}
删除法律保留:
const { DeleteLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteLegalHoldCommand({
Bucket: 'my-protected-bucket',
Key: 'important-document.pdf',
RetentionLegalHoldId: 'legal-case-12345'
});
try {
await client.send(command);
console.log('Legal hold removed');
} catch (err) {
console.error('Error removing legal hold:', err);
}
创建一个采用 Key Protect 加密的存储桶
IBM Key Protect 为存储桶级加密提供加密密钥管理:
const { CreateBucketCommand } = require('ibm-cos-sdk-v2');
const command = new CreateBucketCommand({
Bucket: 'my-encrypted-bucket',
CreateBucketConfiguration: {
LocationConstraint: 'us-south-standard'
},
IBMSSEKPEncryptionAlgorithm: 'AES256',
IBMSSEKPCustomerRootKeyCrn: 'crn:v1:bluemix:public:kms:us-south:...'
});
try {
await client.send(command);
console.log('Encrypted bucket created');
} catch (err) {
console.error('Error creating encrypted bucket:', err);
}
重命名对象
RenameObject 是 IBM 中一个COS特有的原子服务器端操作。 不会传输任何数据——仅密钥发生变化:
const { RenameObjectCommand } = require('ibm-cos-sdk-v2');
const command = new RenameObjectCommand({
Bucket: 'my-bucket',
Key: 'new-object-key', // destination key
RenameSource: 'my-bucket/old-object-key' // source: bucket/key
});
try {
await client.send(command);
console.log('Object renamed successfully');
} catch (err) {
console.error('Error:', err.message);
}
更新对象加密
UpdateObjectEncryption 更新现有对象上的加密密钥引用。 要求该存储桶已配置 IBM、Key Protect 或HPCS:
const { UpdateObjectEncryptionCommand } = require('ibm-cos-sdk-v2');
const command = new UpdateObjectEncryptionCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
await client.send(command);
console.log('Object encryption updated successfully');
} catch (err) {
console.error('Error:', err.message);
}
管理存储桶复制
获取复制配置:
const { GetBucketReplicationCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketReplicationCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Bucket replication configuration retrieved successfully');
console.log('Rules:', JSON.stringify(response.ReplicationConfiguration?.Rules, null, 2));
} catch (err) {
console.error('Error:', err.message);
}
删除复制配置:
const { DeleteBucketReplicationCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketReplicationCommand({ Bucket: 'my-bucket' });
try {
await client.send(command);
console.log('Bucket replication configuration deleted successfully');
} catch (err) {
console.error('Error:', err.message);
}
列出复制故障:
const { ListBucketReplicationFailuresCommand } = require('ibm-cos-sdk-v2');
const command = new ListBucketReplicationFailuresCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Bucket replication failures listed successfully');
console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
console.error('Error:', err.message);
}
重试失败的复制操作:
const { PutBucketReplicationReattemptCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketReplicationReattemptCommand({ Bucket: 'my-bucket' });
try {
await client.send(command);
console.log('Bucket replication reattempt triggered successfully');
} catch (err) {
console.error('Error:', err.message);
}
创建会话
CreateSession 为 IBM Cloud Object Storage 存储桶生成一个临时会话令牌:
const { CreateSessionCommand } = require('ibm-cos-sdk-v2');
const command = new CreateSessionCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Session created successfully');
console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
console.error('Error:', err.message);
}
等待资源准备就绪
等待器会不断轮询资源,直到其达到预期状态,从而无需手动轮询循环。
等待桶的出现:
const { waitUntilBucketExists } = require('ibm-cos-sdk-v2');
try {
await waitUntilBucketExists(
{
client: client,
maxWaitTime: 120, // Maximum wait time in seconds
minDelay: 2, // Minimum delay between checks in seconds
maxDelay: 10 // Maximum delay between checks in seconds
},
{ Bucket: 'my-bucket' }
);
console.log('Bucket exists and is ready');
} catch (err) {
console.error('Bucket did not become available:', err);
}
等待某个对象存在:
const { waitUntilObjectExists } = require('ibm-cos-sdk-v2');
try {
await waitUntilObjectExists(
{
client: client,
maxWaitTime: 60,
minDelay: 1,
maxDelay: 5
},
{
Bucket: 'my-bucket',
Key: 'my-object.txt'
}
);
console.log('Object exists and is ready');
} catch (err) {
console.error('Object did not become available:', err);
}
后续步骤
- 请查阅 Node.js 的 API 参考文档,了解所有可用方法和类型的详细信息
- 请浏览 GitHub 代码库, 查看更多示例和源代码
- 如果您是从以下版本升级,请阅读《 迁移指南 》:v1
- 请查阅 IBM Cloud Object Storage 文档, 了解各项服务的具体功能和最佳实践
- 如需帮助和支持:
- 在 Stack Overflow 上提问时,请使用标签
ibm和object-storage - 在以下平台提交问题:GitHub
- 联系 IBM Cloud 支持团队
- 在 Stack Overflow 上提问时,请使用标签