Gatsby中使用S3Client调用send方法出现TypeError错误
解决AWS SDK v3在Gatsby中调用
client.send时的TypeError问题 核心问题排查
身份池ID配置错误
你代码里把identityPoolId设成了用户池ID(GATSBY_AWS_USER_POOL_ID),这是关键错误。Cognito用户池(User Pool)和身份池(Identity Pool)是两个独立服务:用户池负责用户认证,身份池用来分配访问AWS资源的临时凭证。必须将identityPoolId替换为对应身份池的ID,格式通常为region:xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx。Gatsby环境变量加载问题
虽然Gatsby会暴露GATSBY_前缀的环境变量到浏览器端,但要确认:.env文件里的变量名拼写完全正确- 重启Gatsby开发服务器,确保新环境变量生效
可以在代码中先打印process.env.GATSBY_AWS_S3_REGION等变量,确认它们不是undefined。
修正后的代码示例
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; import { fromCognitoIdentityPool } from "@aws-sdk/credential-provider-cognito-identity"; // 先验证环境变量是否正确加载 console.log("Region:", process.env.GATSBY_AWS_S3_REGION); console.log("Identity Pool ID:", process.env.GATSBY_AWS_IDENTITY_POOL_ID); console.log("Bucket Name:", process.env.GATSBY_AWS_BUCKET_NAME); const client = new S3Client({ region: process.env.GATSBY_AWS_S3_REGION, credentials: fromCognitoIdentityPool({ clientConfig: { region: process.env.GATSBY_AWS_S3_REGION }, // 替换为正确的身份池ID identityPoolId: process.env.GATSBY_AWS_IDENTITY_POOL_ID, // 若为已认证用户上传,需添加logins参数(示例) // logins: { [`cognito-idp.${process.env.GATSBY_AWS_S3_REGION}.amazonaws.com/${process.env.GATSBY_AWS_USER_POOL_ID}`]: 用户ID Token } }) }) export const run = async ({ email, photo }) => { if (!photo) { console.error("未提供上传文件"); return; } const uploadParams = { Bucket: process.env.GATSBY_AWS_BUCKET_NAME, Key: `${email}-${photo.name}`, // 用分隔符避免文件名拼接冲突 Body: photo, // 可选:若需公开访问,添加ACL配置 // ACL: 'public-read' }; try { const data = await client.send(new PutObjectCommand(uploadParams)); console.log("上传成功", data); return data; } catch (err) { console.error("上传失败", err); throw err; // 抛出错误便于调用方处理 } };
额外配置注意事项
- S3桶权限:确保身份池关联的IAM角色拥有
PutObject权限,同时桶的CORS配置允许你的Gatsby域名上传,示例CORS规则:<CORSConfiguration> <CORSRule> <AllowedOrigin>https://你的Gatsby域名.com</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration> - 已认证用户场景:如果需要用户登录后上传,必须在
fromCognitoIdentityPool的logins参数中传入用户的ID Token,身份池才会分配对应认证角色的权限。
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

