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

前端将react-signature-canvas生成的base64转PNG上传S3文件损坏如何解决

核心错误原因
  • S3 预签名 PUT 接口要求直接传入文件原始二进制流,你将 Blob 封装进 FormData 后,传输内容会附带表单分隔符、字段标识等额外信息,存储到 S3 的文件不是纯图片二进制,因此无法打开。
  • 调用 PUT 接口上传时错误使用 application/json 作为 Content-Type,S3 会将上传内容按 JSON 格式处理,同时会导致文件类型识别错误,出现后缀变为 json/html 的问题。
  • 如果你提前删除了 toDataURL() 返回结果的 data:image/png;base64, 前缀,fetch 方法无法识别该字符串为合法 dataURI,转换出的 Blob 本身就是错误内容。
修复后的代码
const fileUpload = async signatureImageSrc => {
  // 如果你之前删除了dataURL前缀,这里要先拼回来
  const completeDataUrl = signatureImageSrc.startsWith('data:') 
    ? signatureImageSrc 
    : `data:image/png;base64,${signatureImageSrc}`;
  // 转换Blob时指定正确的MIME类型
  const signatureImage = await (await fetch(completeDataUrl)).blob();
  // 生成预签名URL的请求保持不变
  const getUploadUrlConfig = {
    headers: {
      "Content-Type": "application/json"
    }
  };
  const fileName = id + "-" + "signature.png";
  const uploadUrlRes = await axios.post(
    "/upload_url", 
    {fileName: fileName, fileType: "image/png"}, 
    getUploadUrlConfig
  );
  // 上传到S3的PUT请求单独配置头信息
  const uploadToS3Config = {
    headers: {
      "Content-Type": "image/png"
    }
  };
  // 直接传Blob作为请求体,不要封装FormData
  await axios.put(uploadUrlRes.data, signatureImage, uploadToS3Config);
};
关键调整说明
  • 保持 dataURL 的前缀完整,确保 fetch 可以正常转换为对应格式的 Blob
  • 预签名 PUT 请求直接传递原始 Blob 作为请求体,不需要封装 FormData
  • PUT 请求的 Content-Type 必须和生成预签名 URL 时提交的 fileType: "image/png" 完全一致,否则S3会判定请求非法或存储错误的文件类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 06:15:07