Reputation: 71
When i try to do a fetch API call in POST with React native (expo SDK 37) using fetch and FormData
, everything works perfectly on IOS but it makes a Network error on Android: [TypeError: Network request failed]
. I have the same error (network error) if I use axios instead of fetch.
If I replace the formData with empty a {}, it works. I've checked on an emulator and on physical devices (with various Android versions), and i tried to play with headers but no result. And my API has a valide let's encrypt certificate
let url = 'https://my-prod-server/webservice';
let formData = new FormData();
formData.append('test1','test1');
formData.append('test2','test2');
let request = await fetch(url, {
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
},
method: 'POST',
body: formData,
})
.then(response => response.json())
.catch(error => console.log('API ERROR: ', error));
return request;
Upvotes: 7
Views: 8844
Reputation: 4721
If all of the above fails, you likely need to increase your client_max_body_size
in your nginx server block configuration:
server {
client_max_body_size 10M;
It's 1M
by default. Not enough for jpegs nowadays.
Upvotes: 1
Reputation: 21
This is still present in Expo 46 and was brought up in a Github Issue.
https://github.com/expo/expo/issues/8323#issuecomment-761675526
It's because Android requires the file.type to be more specific than iOS does.
iOS will accept 'image'
but Android will expect 'image/png'
(or whatever file extension your using)
const uriArray = result.uri.split(".");
const fileExtension = uriArray[uriArray.length - 1]; // e.g.: "jpg"
const fileTypeExtended = `${result.type}/${fileExtension}`; // e.g.: "image/jpg"
data.append('file', {
uri: result.uri,
name: image_name,
type: type: fileTypeExtended
});
The above block works with both iOS and Android and is gratefully copied from @olapiv in the Github thread above.
Upvotes: 2
Reputation: 93
I had the same issue while trying to post image using fetch and FormData on expo SDK 38. The requests were successful on iPhone while it failed with [TypeError: Network request failed] on Android. Upon further investigation, i found out that my requests were not reaching the server at all and issue seemed to be with using FormData only. The requests with FormData were probably timing out/rejected and resulting in the error. I wasted a lot of time searching for answers and trying to implement the solutions suggested but nothing helped, when I came across a post which mentioned XMLHttpRequest. I ended up using XMLHttpRequest instead of fetch in this particular case and it worked like a charm with the FormData on both Android device and iPhone.
Declare a function as follows and replace the values between < and > with appropriate values
function sendXmlHttpRequest(data) {
const xhr = new XMLHttpRequest();
return new Promise((resolve, reject) => {
xhr.onreadystatechange = e => {
if (xhr.readyState !== 4) {
return;
}
if (xhr.status === 200) {
resolve(JSON.parse(xhr.responseText));
} else {
reject("Request Failed");
}
};
xhr.open("POST", <apiEndpoint>);
xhr.setRequestHeader(<headerName>, <value>);
xhr.send(data);
});
}
Now somewhere in your code, create a new FormData object and append any relevant fields/info, then finally call the sendXmlHttpRequest function which will take care of the request.
const photoData = new FormData();
photoData.append("photo", {
uri: <uri of the photo>,
name: filename,
type: "image/jpeg"
});
const response = await sendXmlHttpRequest(photoData);
Upvotes: 7