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

使用AWS S3预签名URL上传文件时content-type始终为binary/octet-stream求助

问题根因与修复方案

S3预签名URL上传时Content-Type被自动修改,核心原因是生成签名时的Content-Type参数与上传时传入的Content-Type不匹配/未显式声明,按以下步骤排查修复即可:

1. 生成预签名URL时必须显式指定ContentType参数

该参数值需要和后续上传时使用的MIME类型完全一致,不可省略。

  • AWS SDK v2 示例代码:
const s3 = new AWS.S3();
const uploadUrl = await s3.getSignedUrlPromise('putObject', {
  Bucket: '你的S3桶名',
  Key: '上传后的文件路径/文件名',
  Expires: 3600, // 签名有效期,单位秒
  ContentType: '对应文件的MIME类型,例:image/jpeg、application/pdf' // 必须添加该参数
})
  • AWS SDK v3 示例代码:
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const s3Client = new S3Client({ region: '你的桶所属区域' });
const command = new PutObjectCommand({
  Bucket: '你的S3桶名',
  Key: '上传后的文件路径/文件名',
  ContentType: '对应文件的MIME类型,和上传时保持完全一致' // 必须显式声明
})
const uploadUrl = await getSignedUrl(s3Client, command, { expiresIn: 3600 })

2. 客户端上传时需严格匹配Content-Type

发起上传请求时,请求头中的Content-Type必须和生成签名时指定的参数值完全一致,不可缺省、不可修改。
以浏览器端fetch上传为例:

await fetch(uploadUrl, {
  method: 'PUT',
  headers: {
    'Content-Type': '和生成签名时完全一致的MIME类型'
  },
  body: 上传的文件对象
})

3. 检查S3桶CORS配置

确认S3桶的跨域资源共享(CORS)规则中,AllowedHeaders列表包含Content-Type,否则浏览器会自动过滤上传请求中的Content-Type头,导致S3收到默认值。
参考CORS配置:

[
  {
    "AllowedOrigins": ["你的业务域名,测试时可填*"],
    "AllowedMethods": ["PUT", "POST"],
    "AllowedHeaders": ["Content-Type"], // 必须包含该值,也可直接填*放行所有头
    "ExposeHeaders": [],
    "MaxAgeSeconds": 3600
  }
]

4. POST表单上传特殊说明

如果使用POST方式的预签名URL上传,除了在生成签名时的Fields参数中添加Content-Type,提交的表单中也必须带上相同值的Content-Type字段。


附提问相关代码截图

代码截图1
代码截图2
代码截图3
代码截图4


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 14:06:05