You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js生成自定义域名S3预签名URL时遇NoSuchKey错误

解决S3自定义域名预签名URL的Key错误问题

问题描述

我使用以下Node.js脚本为绑定自定义域名的S3存储桶文件生成预签名URL:

const tempCreds = await assumeRole(roleArn, roleSessionName); 
const s3 = new S3Client({
        region: process.env.AWS_REGION,
        endpoint: 'https://storage.mydomain.com',
        s3BucketEndpoint: false,
        signatureVersion: 'v4',
        credentials: {
                accessKeyId: tempCreds.AccessKeyId,
                secretAccessKey: tempCreds.SecretAccessKey,
                sessionToken: tempCreds.SessionToken,
        } 
}); 
const bucketName = "storage.mydomain.com"; 
const expirationTime = 5 * 3600; // 5 hour in seconds 
const command = new GetObjectCommand({
        Bucket: bucketName,
        Key: key, 
}); 
const signedUrl = await getSignedUrl(s3, command, { expiresIn: expirationTime });

生成的URL格式类似:
https://storage.mydomain.com/storage.mydomain.com/6703b8f18bd4d8/ap.png?X-Amz-Algorithm=AWS4-HMAC-SHA...

访问该URL时返回错误:

<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Key>storage.mydomain.com/6703b8f18bd4d8/ap.png</Key>
<RequestId>Y3AZXK8CT2W1EA7S</RequestId>
<HostId>H8/cJYWdZRr9JAOquyiJyaF4fee5seG2kzsA4C+IqDYe3zwUlRHXHWlm93fP2SsKXwyUJgKC6yo=</HostId>
</Error>

文件实际存储的Key为6703b8f18bd4d8/ap.png,但AWS将请求识别为Key包含桶名前缀storage.mydomain.com/,导致匹配失败。

原因分析

问题根源在于S3Client配置中的s3BucketEndpoint: false参数。当该参数设为false时,SDK会默认你配置的endpoint是S3的区域通用端点,因此会自动将桶名作为路径前缀拼接至URL中,最终使请求的Key变为桶名/实际Key的格式,与文件真实存储的Key不匹配。

修复方案

将s3BucketEndpoint的值修改为true——因为你的endpoint是直接绑定到特定存储桶的自定义域名,SDK会直接使用该端点发起请求,不再额外拼接桶名到路径中。修改后的完整代码如下:

const tempCreds = await assumeRole(roleArn, roleSessionName); 
const s3 = new S3Client({
        region: process.env.AWS_REGION,
        endpoint: 'https://storage.mydomain.com',
        s3BucketEndpoint: true, // 关键修改:将false改为true
        signatureVersion: 'v4',
        credentials: {
                accessKeyId: tempCreds.AccessKeyId,
                secretAccessKey: tempCreds.SecretAccessKey,
                sessionToken: tempCreds.SessionToken,
        } 
}); 
const bucketName = "storage.mydomain.com"; 
const expirationTime = 5 * 3600; // 5小时(秒)
const command = new GetObjectCommand({
        Bucket: bucketName,
        Key: key, 
}); 
const signedUrl = await getSignedUrl(s3, command, { expiresIn: expirationTime });

修改后生成的URL会变为:
https://storage.mydomain.com/6703b8f18bd4d8/ap.png?X-Amz-Algorithm=AWS4-HMAC-SHA...

此时请求的Key即为正确的6703b8f18bd4d8/ap.png,可以正常访问目标文件。

内容的提问来源于stack exchange,提问作者ap-rxt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:55:54