You need to enable JavaScript to run this app. AWS S3使用PHP生成带UploadId、PartNumber的分片上传预签名URL及报错排查
优惠活动
大模型
产品
解决方案
定价
更多

AWS S3使用PHP生成带UploadId、PartNumber的分片上传预签名URL及报错排查

问题根因说明
  • 核心操作选择错误:分片上传的单分片提交(对应AWS的UploadPart接口)是完全独立于普通单文件上传(PutObject)的操作。你之前用PutObject构建签名命令时,SDK的操作定义里根本没有UploadId、PartNumber这两个参数的字段,构建命令的过程中会直接把这两个非schema内的参数过滤掉,既不会纳入签名计算,也不会拼到最终的预签名URL上。
  • 之前的URL能发起请求但关联不到分片的原因:用PutObject生成的URL触发的是普通单文件上传链路,你传的分片内容会被直接当成普通单文件写到目标Key上,整个过程和你之前初始化的分片上传任务没有任何关联。后续合并分片时,自然会因为找不到任务关联的分片报InvalidPart错误。
  • 文档查找遗漏的原因:JS SDK的getSignedUrl是通用的签名工具,本身不定义支持哪些参数。在通用签名说明页找不到UploadId、PartNumber的相关说明是正常的——这些参数的定义是属于UploadPart这个具体API操作的,不是签名工具本身的。JS代码里传入的操作名uploadPart,会触发SDK加载UploadPart操作的参数schema,自动把这两个参数纳入签名流程。
正确的PHP实现代码
// 基于AWS官方PHP SDK实现,与参考的JS版逻辑完全对齐
$command = $s3Client->getCommand('UploadPart', [
    'Bucket'     => '你的目标Bucket名称',
    'Key'        => '上传目标的对象Key',
    'UploadId'   => $uploadId, // 初始化分片上传接口返回的UploadId
    'PartNumber' => $partNumber, // 从1开始计数的分片序号
]);

// 生成有效期5分钟的预签名URL,和JS代码的过期时间逻辑对齐
$presignedRequest = $s3Client->createPresignedRequest($command, '+5 minutes');
$uploadUrl = (string)$presignedRequest->getUri();
关键注意事项
  • 不要在构建UploadPart命令时传入Body参数:JS代码里传空Body是JS SDK的兼容写法,PHP SDK中传入Body会触发预签名阶段的内容CRC校验,导致客户端实际上传分片时因为签名值和实际内容不匹配被拒绝。
  • 生成的URL不需要手动拼接UploadId、PartNumber参数:SDK构建UploadPart命令时会自动将这两个参数作为查询参数拼到URL上,同时把这些参数值纳入签名计算,避免参数被篡改。
  • 客户端上传分片时,直接用PUT方法请求生成的URL,将分片二进制内容作为请求体发送即可。收到响应后要把返回的ETag和对应PartNumber按顺序保存,后续调用CompleteMultipartUpload时提交这些值,就不会触发InvalidPart错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 14:15:06