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

使用AWS SDK生成PresignedRequest:us-east-1区域URL丢失问题

S3预签名URL在us-east-1区域丢失区域后缀的问题解决

问题原因

us-east-1作为AWS最早推出的S3区域,存在历史遗留的端点设计特殊性:它同时支持带区域后缀的端点(s3.us-east-1.amazonaws.com)和无区域的经典端点(s3.amazonaws.com)。PHP版AWS SDK默认会对us-east-1区域优先使用无区域的经典端点,这就是生成的预签名URL丢失区域后缀的原因——其他区域因不支持无区域端点,SDK会自动生成带区域后缀的URL。

解决办法

1. 显式指定带区域的端点

在创建S3客户端时,直接指定带区域的端点地址,强制SDK以此生成预签名URL:

// 初始化带指定端点的S3客户端
$s3Client = new Aws\S3\S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1',
    'endpoint' => 'https://s3.us-east-1.amazonaws.com'
]);

// 生成GetObject命令
$command = $s3Client->getCommand('GetObject', [
    'Bucket' => 'test',
    'Key' => 'hmtest/img/44 46.pdf'
]);

// 创建预签名请求并获取URL
$presignedRequest = $s3Client->createPresignedRequest($command, '+1 hour');
$presignedUrl = (string) $presignedRequest->getUri();

2. 利用SDK内置方法生成区域端点

如果不想硬编码端点地址,可以使用SDK内置的方法根据区域生成对应的端点:

$s3Client = new Aws\S3\S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1',
    'endpoint' => Aws\S3\S3Client::getEndpointFromRegion('us-east-1')
]);

// 后续生成预签名请求的代码同上

3. 强制使用虚拟主机式端点(适用于SDK 3.x+)

通过配置客户端参数,强制SDK对us-east-1区域使用区域化的虚拟主机端点:

$s3Client = new Aws\S3\S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1',
    'use_path_style_endpoint' => false, // 确保使用虚拟主机式端点
    'endpoint_provider' => Aws\S3\S3EndpointProvider::defaultProvider()
]);

关于手动指定区域的说明

完全可以手动指定区域——在创建S3客户端时通过region参数指定即可,配合上述任意一种端点配置,就能确保生成的预签名URL带区域后缀。

内容的提问来源于stack exchange,提问作者Hiren Makwana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:02:03