在 TypeScript 中操作 S3 与云存储
现代 Web 应用程序越来越频繁地使用云对象存储来存储文件、图像、备份和静态内容。Amazon S3(简单存储服务)是该领域事实上的标准,其 API 受到大多数云服务提供商和本地解决方案的支持,例如 MinIO、DigitalOcean Spaces 或 Yandex Object Storage。在本文中,我们将探讨如何使用官方 AWS SDK 和替代库在 TypeScript 中操作兼容 S3 的存储。
选择用于 TypeScript 中 S3 操作的库
为了从 TypeScript 与 S3 进行交互,有几种流行的解决方案:
- @aws-sdk/client-s3 — 亚马逊官方 SDK,使用 TypeScript 编写,模块化且现代化。
- aws-sdk — 经典版 SDK (v2),仍受支持,但建议迁移到 v3。
- minio — 用于 MinIO 和任何兼容 S3 存储的客户端库,简单轻量。
- s3-client — 基于 fetch API 的极简封装,用于操作 S3。
我们将重点介绍 @aws-sdk/client-s3,因为它是最新且最强大的工具,同时也会展示 minio 的示例,适用于需要轻量级替代方案的场景。
安装与配置
通过 npm 安装必要的包:
npm install @aws-sdk/client-s3 @aws-sdk/lib-storagenpm install --save-dev @types/node typescript对于 MinIO:
npm install minio现在,让我们创建一个基本的 S3 客户端。请确保您拥有环境变量或包含访问密钥的配置。
示例 1:初始化 S3 客户端
import { S3Client } from "@aws-sdk/client-s3";
const s3Client = new S3Client({ region: process.env.AWS_REGION || "us-east-1", credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID!, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!, }, // 对于 MinIO 或本地 S3,请指定 endpoint: // endpoint: "http://localhost:9000", // forcePathStyle: true,});
export default s3Client;请注意参数 forcePathStyle — 对于 MinIO 和其他一些非 AWS 存储,这是必需的。
示例 2:上传文件到 S3
要上传文件,我们使用 PutObjectCommand 命令:
import { PutObjectCommand } from "@aws-sdk/client-s3";import s3Client from "./s3Client";
async function uploadFile(bucket: string, key: string, body: Buffer | string) { const command = new PutObjectCommand({ Bucket: bucket, Key: key, Body: body, ContentType: "application/octet-stream", });
try { const response = await s3Client.send(command); console.log("文件已上传:", response.$metadata.httpStatusCode); return response; } catch (error) { console.error("上传错误:", error); throw error; }}
// 使用:await uploadFile("my-bucket", "uploads/image.png", bufferFromFile);对于大文件的流式上传,请使用 @aws-sdk/lib-storage:
import { Upload } from "@aws-sdk/lib-storage";import { Readable } from "stream";
const upload = new Upload({ client: s3Client, params: { Bucket: "my-bucket", Key: "large-file.zip", Body: Readable.from(fileStream), },});
upload.on("httpUploadProgress", (progress) => { console.log(`已上传:${progress.loaded} / ${progress.total}`);});
await upload.done();示例 3:下载文件
要从存储中获取对象,我们使用 GetObjectCommand:
图书馆中也有
推荐