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

使用预签名请求上传含Unicode文件名的文件至S3时出现403 Forbidden错误的解决咨询

预签名请求上传含Unicode文件名的文件至S3时出现403 Forbidden错误的解决咨询

我最近碰到了一个特别棘手的问题:如果文件名是由Unicode码点构成的,使用预签名请求上传到S3时就会返回403 Forbidden,而且没有任何响应体,调试起来完全摸不着头绪。后来我试着把像ä这样的Unicode字符换成ASCII的a,上传就正常了——这还是我看其他相关问题提到文件名URL编码才想到的测试方向。

先给大家看看我的后端生成预签名URL的代码:

$userId = ...; // 这里的逻辑不影响问题
$filename = ...; // 从POST请求中获取的原始文件名
$safeName = trim(preg_replace('/[^a-z0-9\-_.]/i', '-', $filename), '-'); // AWS只允许特定字符作为对象键
$key = sprintf('user-documents/%s/%s', $userId, $safeName);

$metadata = [
    'type'     => 'USER_DOCUMENT',
    'userId'   => $userId,
    'filename' => $filename, // 这里用的是POST过来的原始文件名
];
$s3 = new S3Client([
    'region'      => getenv('AWS_REGION'),
    'version'     => 'latest',
    'credentials' => CredentialProvider::env(),
]);
$uploadUrl = $s3->createPresignedRequest(
    $s3->getCommand('PutObject', [
        'Bucket'   => getenv('AWS_BUCKET_USER_DATA'),
        'Key'      => $key,
        'Metadata' => $metadata,
    ]),
    '+1 hour',
)->getUri();

$response = [
    'uploadUrl' => $uploadUrl,
    'metadata'  => $metadata,
];

然后是前端负责上传文件到S3的代码:

const file = fileInput.files[0];
const response = await getUploadUrl(file.name); // 这里的file.name就是传给后端POST的文件名
await fetch(response.uploadUrl, {
    method: 'PUT',
    headers: {
        'x-amz-meta-type': response.metadata.type,
        'x-amz-meta-userid': response.metadata.userId,
        'x-amz-meta-filename': response.metadata.filename
    },
    body: file,
}).then(resp => {
    if (!resp.ok) {
        throw new Error('File upload failed: ' + resp.status + ' ' + resp.statusText)
    }
});

我现在的困惑点在于:

  • 生成的uploadUrl里已经包含了URL编码后的原始文件名,按道理AWS那边应该会自动解码吧?毕竟这是他们自己的SDK处理的编码啊
  • 元数据头里我传的是原始未编码的文件名

我实在搞不清楚问题出在哪里,到底需要修改哪部分代码才能解决这个Unicode文件名导致的403问题?另外我的AWS PHP SDK版本是aws/aws-sdk-php@3.334.2,不知道这个版本会不会有影响。

备注:内容来源于stack exchange,提问作者jurchiks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 08:49:30