Reputation: 4663
I am trying to upload an image with react native front end and axios to my back end.
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.
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.
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.
Upvotes: 6
Views: 7664
Reputation: 1
The transformRequest method used here of solving this issue is not working on me so I did a workaround of using JSON.stringify.
const formData = new FormData()
...
MyApiInstance.post('endpoint', JSON.stringify(formData)).then(() ...
hope this help someone.
Upvotes: 0
Reputation: 2035
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);
Upvotes: 1
Reputation: 667
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.
Upvotes: 8
Reputation: 4849
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);
});
Upvotes: 0