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

Amazon S3预签名URL PUT上传报SignatureDoesNotMatch,StringToSign显示GET

问题根因

你遇到的SignatureDoesNotMatch错误核心是预签名URL生成时使用的HTTP方法和实际请求方法不匹配。
S3生成预签名URL的过程中,会将HTTP方法作为必选参数纳入签名计算,生成时用什么方法,实际请求时必须严格使用相同方法。你返回的错误信息里StringToSign字段明确标记为GET,说明你当前前端使用的这个预签名URL,生成时指定的就是GET方法(比如调用AWS SDK时错误使用了getObject操作而非putObject),不管你前端用fetch发什么类型的请求,S3签名校验都会按照生成时的GET方法计算,自然会匹配失败。
你用curl可以正常上传的原因,大概率是测试curl时使用的是另一个正确生成的PUT类型预签名URL,和前端fetch用的不是同一个。

修复步骤

  • 首先修正预签名URL的生成逻辑,明确指定生成PUT类型的预签名URL,以Node.js AWS SDK为例:
// 错误写法:生成的是GET类型的预签名URL
const wrongUrl = s3.getSignedUrl('getObject', {
  Bucket: '你的bucket名',
  Key: 'copy.mp3',
  Expires: 3600
})

// 正确写法:生成的是PUT类型的预签名URL
const correctUrl = s3.getSignedUrl('putObject', {
  Bucket: '你的bucket名',
  Key: 'copy.mp3',
  Expires: 3600,
  ContentType: 'audio/mpeg' // 这里指定的ContentType必须和前端请求时传的完全一致
})
  • 修正你的fetch请求,补充要上传的文件作为请求体:
// 假设你要上传的文件存在file变量里,比如从input[type=file]获取的File对象
fetch("你的PUT类型预签名URL", {
  method: "PUT",
  headers: {
    "content-type": "audio/mpeg" // 必须和生成预签名URL时指定的ContentType完全一致
  },
  body: file, // 这里必须传入要上传的文件内容
  mode: "cors",
  credentials: "omit"
});
  • 检查S3桶的CORS配置,确保允许你的站点(比如http://localhost:3000)发送PUT请求,允许content-type头:
<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>http://localhost:3000</AllowedOrigin>
   <AllowedMethod>PUT</AllowedMethod>
   <AllowedHeader>Content-Type</AllowedHeader>
 </CORSRule>
</CORSConfiguration>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:45:03