I am trying to use the fetch API in order to upload in image to a remote server.
The server address does not use HTTPS protocol, only HTTP. I can’t change that.
I’ve read tons of threads on SO and GitHub but I can’t figure who is the culprit: React-Native, Expo, fetch API or the HTTP Server.
I’ve read that I need to set cleartextTrafficPermitted="true"
in androidManifest
. But I am using Expo in my project so there are no manifest files.
Where do I set the permission needed to POST images to a HTTP server for both Android and iOS ?
I am using EXPO GO on an Android phone for development: Client version: 2.29.6
package.json:
"dependencies": {
"@expo/vector-icons": "^13.0.0",
"@expo/webpack-config": "^19.0.0",
"expo": "~49.0.8",
"expo-camera": "~13.4.2",
"expo-constants": "~14.4.2",
"expo-image": "~1.3.2",
"expo-image-manipulator": "~11.3.0",
"expo-image-picker": "~14.3.2",
"expo-linking": "~5.0.2",
"expo-router": "2.0.0",
"expo-status-bar": "~1.6.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.72.4",
"react-native-animated-spinkit": "^1.5.2",
"react-native-gesture-handler": "~2.12.0",
"react-native-loading-spinner-overlay": "^3.0.1",
"react-native-safe-area-context": "4.6.3",
"react-native-screens": "~3.22.0",
"react-native-web": "~0.19.6",
"expo-file-system": "~15.4.4"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"babel-plugin-module-resolver": "^5.0.0",
"prettier": "^3.0.2"
},
app.json:
{
"expo": {
"name": "lpr-android",
"slug": "lpr-android",
"version": "1.0.0",
"scheme": "lpr",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/favicon.png"
},
"plugins": [
[
"expo-camera",
{
"cameraPermission": "Allow $(PRODUCT_NAME) to access your camera."
}
],
[
"expo-image-picker",
{
"photosPermission": "Allow $(PRODUCT_NAME) to access your image gallery."
}
],
"expo-router"
]
}
}
This is how I use fetch:
const formData = new FormData();
const img = {
uri: compressedImage.uri,
name: compressedImage.uri.split("/").pop(),
type: "image/jpeg",
};
// Append the image to the FormData object with a specified field name
formData.append("image", img);
fetch(HTTP_SERVER_URL, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "multipart/form-data",
},
body: formData,
})
.then((response) => response.json())
.then((data) => {
if (data.error === true) throw new Error(JSON.stringify(data));
setResponse(JSON.stringify(data.response.body));
})
.catch((error) => {
console.log("Error:", error.message);
setError(error.message);
});
where
compressedImage {"base64": null, "height": 1067, "uri": "file:///data/user/0/host.exp.exponent/cache/ImageManipulator/0390fb75-3752-418c-a8c7-5e8837af099e.jpg", "width": 800}