The React Native 0.70 app uses react-native-blob-util to read jpg image file from image picker before uploading it to OSS. Here is the code:
import ReactNativeBlobUtil from "react-native-blob-util"; //v0.19
const fileData = await ReactNativeBlobUtil.fs.readFile(filePath, 'base64'); //filePath is the file path from image picker
const fileData1 = `data:image/jpeg;base64,${fileData}`
The fileData1 was uploaded with fetch:
const response = await fetch(preSignedUrl, {. //preSignedUrl is acquired from backend node server
method: 'PUT',
headers: { 'Content-Type': 'image/jpeg' },
body: fileData1,
})
The image uploaded can't be open. The md5(fileData1) before fetch PUT is the same as the md5 returned from OSS. It may be related to the jpg file format on OSS but not sure where is the issue.
UPDATE:
return of await fetch(filePath) (fetch fileData1 throws error):
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": ""}
You are uploading the base64-encoded image data directly to the OSS (Object Storage Service) using a pre-signed URL.
When you encode the file content in base64 and prepend the data URL schema (
data:image/jpeg;base64), it is suitable for embedding images directly into web pages or CSS files (see "How to display Base64 images in HTML?" for instance).However, for uploading to OSS, you should convert the base64 back to binary data because the storage expects the raw binary format of the image, not its base64-encoded representation.
So you need to convert the base64-encoded string back to binary before uploading. That can be done using the
BloborBufferAPI, but since you are working in a React Native environment, you will have to rely on what is available there. Unfortunately, React Native does not have the same globalBlobconstructor as web browsers, butreact-native-blob-utilprovides a workaround.You need to make sure
base64ToBlobcorrectly converts the base64 string to a binary format thatfetchcan handle. Ifreact-native-blob-utildoes not directly supportbase64ToBlob, you might have to usefetchto create a blob from the base64 string, like:Since
ReactNativeBlobUtil.base64ToBlobdoes not exist, and that thefetch(fileData1)approach results in a network error, you might consider instead to manually converting the base64 string to binary data, and then upload this binary data usingfetch.Try and create a function to convert the base64 string to a binary format that
fetchcan handle as binary data, using theUint8Array:That would manually convert the base64-encoded string to a binary format (
Uint8Array) that is then uploaded.It is a bit lower level and circumvents the need for a
Blob, which should be a good fit considering the capabilities and limitations of React Native's environment.The
atobfunction used in the conversion process is a built-in JavaScript function that decodes a base64-encoded string. However, it might not be available in all React Native environments. Ifatobis not available in your React Native environment, you might need to use a polyfill or an alternative method to decode the base64 string. Libraries such asreact-native-blob-utilmight offer similar functionality, or you can use a third-party library to decode base64 strings.The OP reports in the comments making it work: