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

如何使用s3-request-presigner为PutObjectCommand预签名URL指定需签名的请求头

自定义请求头未被签名的解决方法

你在PutObjectCommand中传入的ACL、CacheControl、ContentType参数,SDK会自动映射为对应的x-amz-acl、Cache-Control、Content-Type请求头,默认会纳入签名范围,不需要额外手动配置signableHeaders。
你遇到的仅host被签名的问题,是因为手动指定signableHeaders时,头名大小写和SDK内部全小写的匹配规则不一致,导致你指定的头未被识别。
你可以直接省略signableHeaders配置即可正常签名所需头:

const command = new PutObjectCommand({
  Bucket: 'mybucket',
  Key: 'file.txt',
  ACL: 'public-read',
  CacheControl: 'public, max-age=1000',
  ContentType: 'text/plain',
});

const signedUrl = await getSignedUrl(s3Client, command, {
  expiresIn: 3600
}); 

如果确实需要手动指定signableHeaders,请确保所有头名全小写,且必须包含host:

const signedUrl = await getSignedUrl(s3Client, command, {
  expiresIn: 3600, 
  signableHeaders: new Set(['cache-control', 'content-type', 'x-amz-acl', 'host'])
});

注意:使用生成的预签名URL发起PUT上传请求时,必须严格携带和签名时完全一致的Cache-Control、Content-Type、x-amz-acl请求头,否则会返回签名不匹配错误。

限制上传大小的实现方案

content-length-range参数仅适用于POST表单上传场景,PUT方式的预签名URL不支持原生限制上传大小,你可以选择以下两种方案:

  • 业务层先校验上传文件大小,再调用预签名URL发起上传
  • 改用POST预签名方式,在策略中配置content-length-range规则,该规则会被纳入签名,超出大小的上传会被S3直接拒绝,示例代码如下:
import { createPresignedPost } from "@aws-sdk/s3-presigned-post";

const { url, fields } = await createPresignedPost(s3Client, {
  Bucket: 'mybucket',
  Key: 'file.txt',
  Expires: 3600,
  Conditions: [
    ["content-length-range", 1024, 10 * 1024 * 1024], // 限制文件大小在1KB到10MB之间
    ["eq", "$CacheControl", "public, max-age=1000"],
    ["eq", "$ContentType", "text/plain"],
    ["eq", "$x-amz-acl", "public-read"]
  ],
  Fields: {
    "Cache-Control": "public, max-age=1000",
    "Content-Type": "text/plain",
    "x-amz-acl": "public-read"
  }
});

生成的fields包含所有需要和文件一起提交的表单字段,前端使用POST方式提交FormData到返回的url即可完成上传。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:36:08