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

React Native使用预签名URL上传图片到Amazon S3后文件损坏如何解决

问题根因

你使用S3预签名PUT URL上传时,错误使用了FormData封装文件:

  • S3的预签名PUT接口会直接把整个请求体当成对象内容存储,不会解析multipart/form-data格式
  • 你用FormData封装图片后,请求体里会额外带上form边界、字段名等文本内容,相当于把这些内容和图片二进制一起存成了文件,最终导致图片损坏
  • 之前自有服务端可以正常使用,是因为你的服务端会主动解析multipart/form-data格式,提取出文件字段的二进制内容;Insomnia测试时你直接上传图片二进制,没有额外的form封装,所以可以正常打开

修复方案

去掉FormData封装,直接上传图片的二进制内容即可,修改后的代码参考如下:

const result = await ImagePicker.launchCameraAsync({
  mediaTypes: ImagePicker.MediaTypeOptions.Images,
  allowsEditing: true,
  aspect: [1, 1],
});
if (!result.cancelled) {
  const resizeResult = await ImageManipulator.manipulateAsync(
    result.uri,
    [{ resize: { height: 400, width: 400 } }],
    { format: "jpeg", compress: 0.8 }
  );
  // 读取本地图片为Blob对象
  const imageBlob = await fetch(resizeResult.uri).then(res => res.blob());
  const config = {
    headers: {
      "Content-Type": "image/jpeg",
      // 如果生成预签名URL时要求单独传x-amz-acl头,这里加上即可
      // "x-amz-acl": "public-read"
    },
  };
  // 直接传Blob作为请求体,不要用FormData
  axios.put(results.data, imageBlob, config)
    .then((res) => console.log(res))
    .catch((e) => console.log(e.response));
}

其他注意事项

  • 确保请求的Content-Type和生成预签名URL时传入的Content-Type完全一致,否则会出现签名不匹配错误
  • 如果axios传输Blob有兼容性问题,也可以换成rn-fetch-blob库直接读取本地文件流上传,兼容性更好

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:54:04