在 Node.js 中操作 S3 和云存储:@aws-sdk/client-s3 库

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

在 JavaScript (Node.js) 中操作 S3 和云存储



S3(Simple Storage Service)是云对象存储的事实标准。无论您使用的是 Amazon S3、Yandex Object Storage、Mail.ru Cloud Storage 还是像 MinIO 这样的本地解决方案,其 API 都是统一的。在本文中,我们将介绍如何使用官方的 AWS SDK v3 从 Node.js 连接到兼容 S3 的存储。



什么是 S3,为什么需要它?

S3 允许您在“存储桶”(buckets)中存储无限数量的文件(对象)。每个对象都有一个唯一的键(路径)和元数据。主要使用场景包括:

  • 存储用户文件(头像、文档)
  • 数据库和日志的备份
  • Web 应用的静态文件(图片、CSS、JS)
  • 存储媒体文件(视频、音频)


安装和配置 AWS SDK v3

从版本 3 开始,AWS SDK 变得模块化。要操作 S3,只需安装一个包:

npm install @aws-sdk/client-s3


您还需要包含访问密钥的环境变量。最好将它们存储在 .env 文件中:

AWS_ACCESS_KEY_ID=your_access_keyAWS_SECRET_ACCESS_KEY=your_secret_keyAWS_REGION=ru-central1S3_ENDPOINT=https://storage.yandexcloud.netS3_BUCKET=my-bucket


连接到兼容 S3 的存储

创建一个带有自定义 endpoint(用于 Yandex Object Storage、MinIO 等)的 S3 客户端:

const { S3Client } = require('@aws-sdk/client-s3');require('dotenv').config();

const s3Client = new S3Client({ region: process.env.AWS_REGION, endpoint: process.env.S3_ENDPOINT, credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, }, forcePathStyle: true, // 对于 MinIO 和一些兼容 S3 的存储很重要});

module.exports = s3Client;


S3 的基本操作



1. 上传文件 (PutObject)

从缓冲区或流上传文件:

const { PutObjectCommand } = require('@aws-sdk/client-s3');const fs = require('fs');

async function uploadFile(filePath, key) { const fileContent = fs.readFileSync(filePath); const command = new PutObjectCommand({ Bucket: process.env.S3_BUCKET, Key: key, Body: fileContent, ContentType: 'image/png', // 指定正确的 MIME 类型 });

try { const response = await s3Client.send(command); console.log('文件已上传:', response.$metadata.httpStatusCode); return `https://storage.yandexcloud.net/${process.env.S3_BUCKET}/${key}`; } catch (err) { console.error('上传错误:', err); }}


2. 下载文件 (GetObject)

获取对象并保存到本地:

const { GetObjectCommand } = require('@aws-sdk/client-s3');const fs = require('fs');const stream = require('stream');const { promisify } = require('util');const pipeline = promisify(stream.pipeline);

async function downloadFile(key, destinationPath) { const command = new GetObjectCommand({ Bucket: process.env.S3_BUCKET, Key: key, });

try { const response = await s3Client.send(command); const writeStream = fs.createWriteStream(destinationPath); await pipeline(response.Body, writeStream); console.log('文件已下载:', destinationPath); } catch (err) { console.error('下载错误:', err); }}


3. 获取对象列表 (ListObjectsV2)

用于显示存储桶中的文件:

const { ListObjectsV2Command } = require('@aws-sdk/client-s3');

async function listFiles(prefix = '') { const command = new ListObjectsV2Command({ Bucket: process.env.S3_BUCKET, Prefix: prefix, MaxKeys: 100, });

try { const response = await s3

推荐