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

React Native用预签名URL传OSS遇403,Postman可正常上传

解决React Native 0.70中fetch上传阿里云OSS预签名URL返回403及图片损坏问题

核心问题分析

阿里云OSS的预签名URL校验严格,请求的头信息、请求体格式必须和生成预签名时的参数完全匹配。你遇到的403是因为fetch请求多带了Content-Type头(和预签名生成条件不匹配),而base64上传损坏是因为直接发送了base64字符串而非原始二进制数据。Postman成功的关键是关闭Content-Type头并上传原始二进制,这就是排查方向。


具体解决方案

1. 移除fetch请求中的Content-Type头

预签名生成时如果未指定Content-Type作为签名条件,前端请求绝对不能添加这个头,否则会触发签名校验失败返回403。

// 正确的fetch请求示例
const uploadImage = async (presignedUrl, fileUri) => {
  // 先获取原始二进制文件流(以react-native-blob-util为例)
  const blobResponse = await RNBlobUtil.fetch('GET', fileUri);
  const binaryData = blobResponse.data;

  const response = await fetch(presignedUrl, {
    method: 'PUT',
    headers: {}, // 不要设置任何Content-Type相关头
    body: binaryData // 直接传原始二进制数据
  });

  if (response.ok) {
    console.log('上传成功');
  } else {
    console.error('上传失败:', await response.text());
  }
};

2. 正确读取本地文件的二进制数据

使用react-native-blob-util时,要直接获取文件的原始二进制,避免转成base64或其他格式:

import RNBlobUtil from 'react-native-blob-util';

// 读取本地图片为二进制数据
const getBinaryFile = async (fileUri) => {
  const blob = await RNBlobUtil.fetch('GET', fileUri);
  return blob.data; // 这里返回的就是原始二进制Buffer
};

3. 检查后端预签名生成逻辑

确认后端生成预签名URL时,没有将Content-Type加入签名参数。如果后端代码中指定了Content-Type(比如application/octet-stream),前端请求必须严格携带完全一致的头;如果后端未指定,前端一定不能加这个头。

4. 修复base64上传的图片损坏问题

如果必须使用base64上传,需要先将base64字符串转成原始二进制再发送,不能直接传base64文本:

// base64转二进制示例
const base64ToBinary = (base64Str) => {
  // 去掉base64前缀(如果有的话)
  const pureBase64 = base64Str.replace(/^data:image\/jpeg;base64,/, '');
  // 转成Uint8Array二进制数据
  return Uint8Array.from(atob(pureBase64), char => char.charCodeAt(0));
};

// 上传调用
const binaryData = base64ToBinary(yourBase64String);
await fetch(presignedUrl, {
  method: 'PUT',
  headers: {},
  body: binaryData
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:16:10