如何使用AWS SDK for JavaScript V3从Node.js上传图片到S3存储桶?
使用AWS SDK for JavaScript v3在Node.js中上传图片到S3存储桶
第一步:安装依赖
弃用旧版aws-sdk包,安装v3专属的S3客户端及分块上传工具:
npm install @aws-sdk/client-s3 @aws-sdk/lib-storage
第二步:安全配置凭证(禁止硬编码)
v3不再推荐在代码中直接写入密钥,优先使用以下安全方案:
- 环境变量:项目根目录创建
.env文件,添加:
安装AWS_ACCESS_KEY_ID=你的访问密钥ID AWS_SECRET_ACCESS_KEY=你的私有访问密钥 AWS_REGION=存储桶所在区域(如us-east-1)dotenv包后在代码开头加载:require('dotenv').config(); - 本地凭证文件:在
~/.aws/credentials(Linux/macOS)或C:\Users\<用户名>\.aws\credentials(Windows)中配置:[default] aws_access_key_id=你的访问密钥ID aws_secret_access_key=你的私有访问密钥 - IAM角色:若代码运行在EC2、Lambda等AWS服务上,直接为资源绑定带
s3:PutObject权限的IAM角色,无需手动配置凭证。
第三步:上传代码示例
示例1:小文件直接上传(适合几MB以内图片)
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3"); const fs = require('fs'); require('dotenv').config(); // 初始化S3客户端 const s3Client = new S3Client({ region: process.env.AWS_REGION }); // 上传函数 async function uploadImageToS3(bucketName, filePath, s3Key) { try { const fileContent = fs.readFileSync(filePath); // 务必指定ContentType,否则图片会被识别为二进制文件 const params = { Bucket: bucketName, Key: s3Key, // S3内的存储路径/文件名,如"user-avatars/2024-05-avatar.jpg" Body: fileContent, ContentType: 'image/jpeg' // 根据图片类型调整,如image/png、image/webp }; const command = new PutObjectCommand(params); const response = await s3Client.send(command); console.log('图片上传成功:', response); return response; } catch (err) { console.error('上传失败:', err); throw err; } } // 调用示例 uploadImageToS3('你的存储桶名称', './local-test.jpg', 'user-avatars/uploaded-test.jpg');
示例2:大文件分块上传(支持断点续传,适合几十MB以上图片)
借助@aws-sdk/lib-storage的Upload类自动处理分块与重试:
const { S3Client } = require("@aws-sdk/client-s3"); const { Upload } = require("@aws-sdk/lib-storage"); const fs = require('fs'); require('dotenv').config(); const s3Client = new S3Client({ region: process.env.AWS_REGION }); async function uploadLargeImageToS3(bucketName, filePath, s3Key) { try { const fileStream = fs.createReadStream(filePath); fileStream.on('error', (err) => console.error('文件流异常:', err)); const uploadParams = { Bucket: bucketName, Key: s3Key, Body: fileStream, ContentType: 'image/jpeg' }; const upload = new Upload({ client: s3Client, params: uploadParams, partSize: 10 * 1024 * 1024, // 自定义分块大小,默认5MB queueSize: 4 // 并发上传的分块数量 }); // 监听上传进度 upload.on('httpUploadProgress', (progress) => { console.log(`上传进度: ${Math.round((progress.loaded / progress.total) * 100)}%`); }); const response = await upload.done(); console.log('大文件上传成功:', response); return response; } catch (err) { console.error('大文件上传失败:', err); throw err; } } // 调用示例 uploadLargeImageToS3('你的存储桶名称', './large-test.jpg', 'banner-images/uploaded-large-banner.jpg');
关键注意事项
- IAM权限:确保凭证对应的IAM用户/角色拥有
s3:PutObject权限,存储桶策略也要允许该操作。 - CORS配置:若通过前端API中转上传,需在S3存储桶的CORS规则中允许对应来源和HTTP方法。
- ContentType:必须匹配图片实际类型,否则浏览器打开图片链接时会触发下载而非直接显示。
内容的提问来源于stack exchange,提问作者Unnikrishnan KJ
相关产品推荐
相关产品推荐

