React Native 0.70上传JPG至OSS后无法打开问题排查
React Native上传JPG到OSS后无法打开问题排查
当前实现代码
读取图片文件
import ReactNativeBlobUtil from "react-native-blob-util"; //v0.19 const fileData = await ReactNativeBlobUtil.fs.readFile(filePath, 'base64'); //filePath是图片选择器返回的文件路径 const fileData1 = `data:image/jpeg;base64,${fileData}`
上传到OSS
const response = await fetch(preSignedUrl, { //preSignedUrl从后端node服务器获取 method: 'PUT', headers: { 'Content-Type': 'image/jpeg' }, body: fileData1, })
问题现象
- 上传完成后,OSS上的图片无法打开
- 上传前
fileData1的MD5与OSS返回的文件MD5一致
更新信息:本地fetch文件路径的返回结果
LOG responsefetch in uploadTOOSS: {"_bodyBlob": {"_data": {"__collector": [Object], "blobId": "44313295-9de3-4dfe-b9be-bbdef6110f4b", "lastModified": 0, "name": "rn_image_picker_lib_temp_9373b67e-6f10-4932-b743-f2155da4fca8.jpg", "offset": 0, "size": 47367, "type": "image/jpeg"}}, "_bodyInit": {"_data": {"__collector": [Object], "blobId": "44313295-9de3-4dfe-b9be-bbdef6110f4b", "lastModified": 0, "name": "rn_image_picker_lib_temp_9373b67e-6f10-4932-b743-f2155da4fca8.jpg", "offset": 0, "size": 47367, "type": "image/jpeg"}}, "bodyUsed": false, "headers": {"map": {"content-type": "image/jpeg"}}, "ok": false, "status": 0, "statusText": "", "type": "default", "url": ""}
问题原因分析
核心问题是你上传的是Data URI格式的字符串,但OSS期望接收的是原始二进制图片数据。虽然MD5一致说明数据没有丢失,但OSS存储的内容包含了data:image/jpeg;base64,前缀,导致文件不再是标准JPG二进制格式,无法被图片查看器识别。
另外,fetch(filePath)返回status 0是因为React Native的fetch不支持直接读取本地文件路径,属于正常现象,和上传问题无关。
解决方案
方案1:直接上传二进制文件(推荐)
利用react-native-blob-util的原生上传能力,直接读取文件二进制流上传,避免base64转换的额外开销和格式问题:
import ReactNativeBlobUtil from "react-native-blob-util"; const response = await ReactNativeBlobUtil.fetch( 'PUT', preSignedUrl, { 'Content-Type': 'image/jpeg' }, ReactNativeBlobUtil.wrap(filePath) // 直接包装本地文件路径,以二进制形式上传 );
方案2:将base64字符串转换回二进制再上传
如果坚持用fetch上传,需去掉Data URI前缀并将base64转换为二进制数据:
// 去掉Data URI前缀,仅保留base64内容 const base64Content = fileData1.replace('data:image/jpeg;base64,', ''); // 将base64转换为ArrayBuffer const buffer = Uint8Array.from(atob(base64Content), c => c.charCodeAt(0)); const response = await fetch(preSignedUrl, { method: 'PUT', headers: { 'Content-Type': 'image/jpeg' }, body: buffer, });
内容的提问来源于stack exchange,提问作者user938363
相关产品推荐
相关产品推荐

