如何解决Node.js18+AWS SDK v3中预签名URL生成的date.getUTCFullyear报错?
解决AWS SDK v3 getSignedUrl报错"date.getUTCFullyear is not a function"
1. 确认getSignedUrl的正确导入方式
AWS SDK v3中,getSignedUrl需要从@aws-sdk/s3-request-presigner包单独导入,而非SDK核心包,确保代码顶部有:
// ES模块写法 import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; // CommonJS写法 const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
同时要保证S3客户端和命令的导入正确:
// ES模块写法 import { S3Client, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3"; // CommonJS写法 const { S3Client, GetObjectCommand, PutObjectCommand } = require("@aws-sdk/client-s3");
2. 检查日期相关参数格式
报错中的getSignedUrl拼写错误(正确应为getUTCFullYear),通常是由于传递了非Date类型的过期时间参数导致的。如果你的命令中指定了Expires,必须确保它是Date对象,或是表示秒数的数字(SDK会自动转换为Date):
// 错误示例:字符串日期 const command = new GetObjectCommand({ Bucket: params.Bucket, Key: params.Key, Expires: "2024-12-31" }); // 正确示例1:Date对象 const command = new GetObjectCommand({ Bucket: params.Bucket, Key: params.Key, Expires: new Date("2024-12-31") }); // 正确示例2:秒数(如3600秒后过期) const command = new GetObjectCommand({ Bucket: params.Bucket, Key: params.Key, Expires: 3600 });
3. 规范getSignedUrl调用方式
你可以通过第三个参数直接设置过期时间,无需在命令中传递:
const url = await getSignedUrl(s3, command, { expiresIn: 3600 }); // expiresIn为秒数
4. 统一SDK版本避免兼容性问题
确保@aws-sdk/client-s3和@aws-sdk/s3-request-presigner版本一致,执行以下命令更新到最新兼容版本:
npm install @aws-sdk/client-s3@latest @aws-sdk/s3-request-presigner@latest
修正后的完整示例代码
const { S3Client, GetObjectCommand, PutObjectCommand } = require("@aws-sdk/client-s3"); const { getSignedUrl } = require("@aws-sdk/s3-request-presigner"); const s3 = new S3Client({ signatureVersion: 'v4' }); try { let command; if (flag === 'DOWN') { command = new GetObjectCommand({ Bucket: params.Bucket, Key: params.Key, }); delete params.Metadata; logger.info({ reqp: { headers: { rid } }, message: `Command invoked is ${command.constructor.name}`, }); } else { command = new PutObjectCommand(params); } const url = await getSignedUrl(s3, command, { expiresIn: 3600 }); // 后续处理生成的预签名URL } catch (err) { logger.error({ reqp: { headers: { rid } }, message: `Error while generating presigned URL: ${err.message}`, error: err }); }
内容的提问来源于stack exchange,提问作者Akshat Vyas
相关产品推荐
相关产品推荐

