'React Native + Expo + Axios file upload not working because axios is not sending the form data to the server
I am trying to upload an image with react native front end and axios to my back end.
This is how pic the image
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: false,
aspect: [9, 16],
quality: 1,
});
console.log(result.uri);
if (!result.cancelled) {
console.log(result);
setPhoto(result);
}
};
now you can see clearly that I am setting up the photo state with the ImagePicker library.
Then I create a form data instance:
let img_to_upload = {
type: 'image/jpeg',
name: 'random-file-name',
uri: Platform.OS === 'android' ? photo.uri : photo.uri.replace('file://', ''),
};
let formData = new FormData();
formData.append("title", 'this is tandom text');
formData.append("file", img_to_upload);
here you can see clearly I have initiated a formdata object and then adding two fields to the form.
- title
- file
And last but not least, I send this to the server:
axios({
method: 'POST',
url: U_R_L,
data: formData,
transformRequest: (d) => d,
headers: {
"Content-Type": "multipart/form-data; charset=utf-8; boundary=------random-boundary",
}
})
.then((response) => {
console.log("response : ");
console.log(response.data);
}, (error) => {
console.log("error : ");
console.log(error);
})
.then(() => {
setProgress(false);
});
But it never sends any file to the server.
Here is the error:
But when I test the same endpoint with my REST client, it works.
Solution 1:[1]
Axios' FormData is broken since v0.25 for react-native. They tried to optimize the FormData detection util for no real reason. Unfortunately, the proper detection fails for non browser environments.
You can find a workaround here for now: https://github.com/axios/axios/issues/4406#issuecomment-1048693170
TL;DR
const formData = new FormData();
...
const response = await axios.post('/URL', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
transformRequest: (data, headers) => {
return formData; // this is doing the trick
},
});
Just pass a transformRequest and return your formData and everything will "work" magically again. This is a workaround though (I've spent 5 hours on this issue) and should hopefully be fixed in an upcoming version.
Solution 2:[2]
there is no no need to set the content-type
header in your request. It automatically identify your request contains the buffer data
. so you just pass the request without setting multipart content-type
header.
I'm also confused with this same issue. my MacBook is sending the request without any issue by using postman, and my android device is having issues sending the multipart
request.
Solution
Poor network connection is the major issue in this part. So just change your mobile network to any other network, which has the better internet connectivity. and check again. surely it solved your issue
Native javascript query for sending the multipart data - axios is also using this same native library
var data = new FormData();
data.append("file", {
name: 'image.png',
type: 'image/png,
uri: 'file:///file-cache-url'
}, "image.png");
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "http://127.0.0.1:3000/data/upload");
xhr.send(data);
Solution 3:[3]
Fetch image as BLOB
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", "FILE_URI_HERE", true);
xhr.send(null);
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Hirbod |
Solution 2 | |
Solution 3 | BYIRINGIRO Emmanuel |