Node.js AWS Lambda调用s3.listObjectsV2报错:s3.listObjectsV2 is not a function的问题排查
解决AWS Lambda中
s3.listObjectsV2 is not a function错误的方案 嘿,我来帮你搞定这个问题!你碰到的s3.listObjectsV2 is not a function错误,主要是AWS SDK版本不匹配导致的,另外你代码里的异步处理逻辑也有坑,咱们一步步来解决:
一、核心错误原因:SDK版本不兼容
你现在的代码是AWS SDK v2的写法,但如果你的Lambda环境里装的是SDK v3,就会出现这个报错——因为v3完全重构了API结构,不再有listObjectsV2这种直接挂载在S3实例上的方法,而是用命令式的调用方式。
另外,如果你的Lambda用的是默认的SDK v2,但版本过于老旧,也可能出现这个问题(不过这种情况比较少见)。
二、针对不同SDK版本的修正方案
方案1:继续使用AWS SDK v2(Lambda默认环境通常是v2)
先把代码里的回调逻辑改成async/await形式,因为你的handler已经声明为async,用回调会导致逻辑执行顺序混乱(比如你现在的代码会在listAllKeys还没跑完就打印allKeys.length,结果肯定是0)。修正后的代码如下:
const AWS = require('aws-sdk'); const awsOptions = { region: "us-east-1" }; const s3 = new AWS.S3(awsOptions); exports.handler = async (event, context) => { const SrcBucket = event.Records[0].s3.bucket.name; const bucketParams = { Bucket: SrcBucket, Prefix: 'Temp/', }; let allKeys = []; let continuationToken = null; // 循环处理分页结果 do { if (continuationToken) { bucketParams.ContinuationToken = continuationToken; } // 用promise+await替代回调,保证异步等待 const data = await s3.listObjectsV2(bucketParams).promise(); // 提取所有对象的Key allKeys = allKeys.concat(data.Contents.map(content => content.Key)); // 更新续传令牌,处理分页 continuationToken = data.NextContinuationToken; if (data.IsTruncated) { console.log("获取更多对象列表..."); } } while (continuationToken); console.log(`总共有 ${allKeys.length} 个对象`); return { statusCode: 200, body: JSON.stringify({ totalKeys: allKeys.length, keys: allKeys }) }; };
方案2:升级到AWS SDK v3(官方推荐的新版本)
如果想改用v3,需要先安装对应的依赖(本地开发时执行npm install @aws-sdk/client-s3),然后代码要改成命令式的调用方式:
const { S3Client, ListObjectsV2Command } = require("@aws-sdk/client-s3"); const client = new S3Client({ region: "us-east-1" }); exports.handler = async (event, context) => { const SrcBucket = event.Records[0].s3.bucket.name; let params = { Bucket: SrcBucket, Prefix: 'Temp/', }; let allKeys = []; let continuationToken = null; do { if (continuationToken) { params.ContinuationToken = continuationToken; } // 创建ListObjectsV2命令并发送请求 const command = new ListObjectsV2Command(params); const response = await client.send(command); allKeys = allKeys.concat(response.Contents.map(content => content.Key)); continuationToken = response.NextContinuationToken; if (response.IsTruncated) { console.log("获取更多对象列表..."); } } while (continuationToken); console.log(`总共有 ${allKeys.length} 个对象`); return { statusCode: 200, body: JSON.stringify({ totalKeys: allKeys.length, keys: allKeys }) }; };
三、额外注意事项
- 如果你是自己打包代码上传Lambda,一定要确认package.json里的SDK版本,不要同时混用v2和v3的依赖,否则会出现奇怪的兼容性问题。
- Lambda默认的执行环境(比如Node.js 18+)已经预装了SDK v3,如果你用的是这个环境,直接用方案2的代码就行。
内容的提问来源于stack exchange,提问作者Aniruddha
相关产品推荐
相关产品推荐

