Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POST FormData still creates Network Error on Android with 0.27.2 #4800

Open
zaubara opened this issue Jun 20, 2022 · 51 comments
Open

POST FormData still creates Network Error on Android with 0.27.2 #4800

zaubara opened this issue Jun 20, 2022 · 51 comments

Comments

@zaubara
Copy link

zaubara commented Jun 20, 2022

Describe the bug

On Android in Expo 45 / React Native 0.68 with Hermes (and Flipper), POSTing a FormData object fails instantly with a Network Error. Works on iOS. Axios 24 works and seems to be the last reliable version.

To Reproduce

const fd = new FormData()
fd.append('some_text', text1)
fd.append('more_text', text2)
fd.append('only_text', text3)
try {
    const response = await api.post('endpoint', fd)
    return response
} catch (e) {
    console.log(e)
    return
}

Expected behavior

No network error.

Environment

  • Axios Version: 0.27.2
  • OS: Android 11
  • Additional Library Versions: Expo 45, React Native 0.68
@DigitalBrainJS
Copy link
Collaborator

Solving the issue that can occur in the ReactNative environment is difficult, as it seems that none of the contributors use RN in their daily work in order to be able to quickly create a test environment to fix the bug. At the same time, reports on the workability of FormData in ReactNative are quite inconsistent.

Could you please run this test code on the affected platform and post the log here?

import axios from "axios";
import utils from "axios/lib/utils.js";

const form = new FormData();
const prototype = FormData.prototype;

console.log(
  JSON.stringify({
    VERSION: axios.VERSION,
    client: typeof navigator !== "undefined" && navigator.userAgent,
    node: typeof process !== "undefined" && process.version,
    isFormData: utils.isFormData(form),
    toString: String(form),
    stringTag: form[Symbol.toStringTag],
    constructor: prototype.constructor,
    props: Object.getOwnPropertyNames(prototype)
  })
);

@zaubara
Copy link
Author

zaubara commented Jun 20, 2022

Sure:
{"VERSION":"0.27.2","isFormData":true,"toString":"[object Object]","props":["constructor","append","getParts"]}

@zaubara
Copy link
Author

zaubara commented Jun 20, 2022

I think it's more readable without the stringify:
Bildschirmfoto 2022-06-20 um 16 14 34

Weirdly enough, iOS shows the same output stringified, but works - however, there's no "exception":
Bildschirmfoto 2022-06-20 um 16 58 21

@mantusuff420
Copy link

Same issue for me too

@DigitalBrainJS
Copy link
Collaborator

@zaubara thanks! It seems we need an additional test since it's not a typical problem with FormData instance detection.
One more test:

  function isStandardBrowserEnv() {
    let product;
    if (typeof navigator !== 'undefined' && (
      (product = navigator.product) === 'ReactNative' ||
      product === 'NativeScript' ||
      product === 'NS')
    ) {
      return false;
    }

    return typeof window !== 'undefined' && typeof document !== 'undefined';
  }

  function isFormData(thing) {
    const pattern = '[object FormData]';
    return thing && (
      (typeof FormData === 'function' && thing instanceof FormData) ||
      toString.call(thing) === pattern ||
      (typeof thing.toString === 'function' && thing.toString() === pattern)
    );
  }

  console.log('product', typeof navigator !== 'undefined' && navigator.product);
  console.log('Platform', typeof Platform !== 'undefined' && Platform);
  console.log('axios:isStandardBrowserEnv', isStandardBrowserEnv());
  console.log('axios:isFormData', isFormData(new FormData()));

  ((name) => {
    try {
      const xhr = new XMLHttpRequest();
      xhr.open('POST', 'https://httpbin.org/post');
      const formdata = new FormData();
      const text = 'This is awesome';
      formdata.append('title', text);
      xhr.onerror = console.warn;
      xhr.onloadend = () => {
        console.log(`[${name}] ${JSON.parse(xhr.response).form.title}`);
      }
      xhr.send(formdata);
    } catch (err) {
      console.warn(err);
    }
  })('without content type');

  ((name) => {
    try {
      const xhr = new XMLHttpRequest();
      xhr.open('POST', 'https://httpbin.org/post');
      const formdata = new FormData();
      const text = 'This is awesome';
      formdata.append('title', text);

      xhr.setRequestHeader('Content-Type', 'multipart/form-data');

      xhr.onerror = console.warn;
      xhr.onloadend = () => {
        console.log(`[${name}] ${JSON.parse(xhr.response).form.title}`);
      }
      xhr.send(formdata);
    } catch (err) {
      console.warn(err);
    }
  })('with content type')

@JonhnyDev
Copy link

Same issue for me too

@zaubara
Copy link
Author

zaubara commented Jun 24, 2022

Different device, but still getting the same error, so it should be identical:

product ReactNative
Platform false
axios:isStandardBrowserEnv false
axios:isFormData true
[with content type] This is awesome
[without content type] This is awesome

@tanengsiang
Copy link

I also facing this issue for the network error, below is the screen shot.
error_resubmit

work fine in iOS simulator but in my android
device will pop out above error .

below is my api code :

resubmitLeave = ()=>{ // This api is post the resubmit leave record

    LoadingModal.show();
    const form = new FormData();

    Object.keys(this.state).forEach((key)=>{
        if (key == 'Hours'){
            form.append(key, parseFloat(this.state[key]));
        }else if (key == 'Days'){
            form.append(key, this.state.LeaveKind == 'Hourly' ? 0 : parseFloat(this.state[key])); 
        }else{

            form.append(key, this.state[key]);
        }
    })
    
    api.post('api/ResubmitLeaveForm', form).then((res) => {
        
        console.log(res, '----------------------  from resubmit leave respond')
        
        AlertBox.showModal('success', '', 'Resubmit Leave Form Success!');
        LoadingModal.close();
       this.props.onFinish();
   
    }).catch((err) => {
        console.error(err, '----------------------  from resubmit leave respond err');
        AlertBox.showModal('error', '', err[0].Message[0]);
        this.props.onFinish();
        if (err && !(err instanceof Error)) {
            let temp = [];
            let error = [];
            error = err[0]['Message'];
            error.forEach((each) => {
                temp.push(each);
            })
            this.setState({
                message: {
                    status: true,
                    error: temp
                }
            })
        } else {
            //System error or runtime error
        }
        LoadingModal.close();
    
    })

axios version : "^0.19.0",
expo version : 41,
OS : Android 10 ,
React Native Version : 0.69.0

@Nantris
Copy link

Nantris commented Jun 28, 2022

@zaubara do you see any network request in the debugger's Network tab from Axios?

We seem to be having this same issue, and we do not see Axios creating any network request in the Network tab, but this may be a limitation of Flipper. But the Network Plugin doesn't show Axios making any requests either, and other network requests do show up there. It seems like Axios isn't even sending the request.

Edit: Actually, rebooting our development machine seems to have resolved this for us, but that's rather baffling.

@mlazari
Copy link

mlazari commented Aug 23, 2022

The issue is that axios is setting a wrong Content-Type header if you don't pass it explicitly. See #4823 (comment)

@Nantris
Copy link

Nantris commented Aug 26, 2022

@mlazari we explicitly set the 'Content-Type': 'application/x-www-form-urlencoded' but we still have the issue.

@mlazari
Copy link

mlazari commented Aug 27, 2022

@slapbox That doesn't change anything since you set the same value as the default. I think you must use 'Content-Type': 'multipart/form-data' when you use FormData. From my debugging if you send FormData with the default 'Content-Type': 'application/x-www-form-urlencoded' it doesn't make the request at all on Android and XMLHttpRequest.onerror is called here: https://github.com/axios/axios/blob/v0.27.2/lib/adapters/xhr.js#L116 which causes the rejection with "Network Error".

Note that if you use FormData from form-data you'll likely need this workaround: #4412 (comment). But recently I found that there is a global FormData available in React Native that you can use and that works without that workaround.

@jjspierx
Copy link

I was having the same issue. Spent and entire day on it. Rolled back to Axios 0.24.0 and it started working.

@hellocaio
Copy link

React Native

Hey guys, I spent hours on this and the only way I could get it to work was to downgrade to 0.24.0 as @jjspierx mentioned.

  const formData = new global.FormData()
  formData.append('file', data)

  const response: PostImageResponse = await http({
    method: 'POST',
    url: `/document/link/${docId}`,
    headers: {
      'Content-Type': 'multipart/form-data',
    },
    data: formData,
  })

Where http is a utility that sets up and calls axios along with the config object parameter shown above.

Version:
React: 18.0.0
Expo: ~46.0.9
Axios: 0.24.0

@Rhadammanthis
Copy link

This is still happening with
react-native: 0.64.0
but I'm glad(?) to add that downgrading axios worked for us too

@Josef-Marie
Copy link

same issue too
this is what am getting

FormData {
"_parts": Array [
Array [
"Image",
Object {
"name": "my_image.jpg",
"type": "image/jpg",
"uri": undefined,
},
],
Array [
"user",
"18",
],
Array [
"Message",
"Good to go ",
],
Array [
"symptoms",
"Abortion",
],
Array [
"cattleType",
"Inka zikamwa",
],
Array [
"Sector",
"Rwimiyaga",
],
],
}
[AxiosError: Network Error]

@hellocaio
Copy link

hellocaio commented Jan 20, 2023

I got it to work with "axios": "0.24.0" only.

@paruckerr
Copy link

react: 17.0.1 => 17.0.1
react-native: 0.64.3 => 0.64.3

Still not working with "axios": "^0.24.0"

@paruckerr
Copy link

I resolve the network error problem setting file like this

{
    name: 'files',
    type: 'image/png',
    uri: Platform.select({ ios: file.uri.replace('file://', ''), android: file.uri }),
}

info

react: 17.0.1
react-native: 0.64.3
react-native-image-crop-picker: ^0.38.1

@Roucoz
Copy link

Roucoz commented Jan 25, 2023

only downgrading to version 0.24.0 works.

@paruckerr
Copy link

only downgrading to version 0.24.0 works.

I had already downgraded, but the way I was passing the object caused the error too, so I added the info above if helps.

@Nantris
Copy link

Nantris commented Jan 25, 2023

Does this still affect versions 1.0.0 and above? Can anyone report their findings?

@pnodet
Copy link

pnodet commented Jan 30, 2023

Fixed by add correct content type using the rpm mime pkg.

import mime from "mime";

const newImageUri =  "file:///" + imageUri.split("file:/").join("");

const formData = new FormData();
formData.append('image', {
 uri : newImageUri,
 type: mime.getType(newImageUri),
 name: newImageUri.split("/").pop()
});

@mateusfg7
Copy link

mateusfg7 commented Jan 30, 2023

I resolve the network error problem setting file like this

{
    name: 'files',
    type: 'image/png',
    uri: Platform.select({ ios: file.uri.replace('file://', ''), android: file.uri }),
}

info

react: 17.0.1
react-native: 0.64.3
react-native-image-crop-picker: ^0.38.1

This works for me too, thanks!

Environment:

react: 18.1.0
react-native: 0.70.5
expo: ^47.0.7
expo-image-picker: ~14.0.2
axios: ^1.2.2

@mateusfg7
Copy link

mateusfg7 commented Jan 30, 2023

Does this still affect versions 1.0.0 and above? Can anyone report their findings?

@slapbox I'm on the v1.2.2, and I was facing the same issue until I try the solution of @paruckerr, and finally works!

Downgrading to 0.24.0 didn't work.

@PrimulaX
Copy link

I had a similar problem about a year ago and didn't remember how I resolved it. And again I have this problem, last time what I remember, it was okHttp bug on android, does anyone have more info about this?

@hemaliVadher
Copy link

FormData still creates Network Error on Android with 0.27.2. I have [AxiosError: Network Error] while uploading a document via react-native-document-picker@8.1.2. Please give me suggestions on how to resolve this.

@OKT92
Copy link

OKT92 commented Mar 1, 2023

Solved my problem after adding headers content-type "multipart/form-data" instead of "x-www-form-urlencoded".

Axios version: 1.3.4

@zaubara
Copy link
Author

zaubara commented Mar 1, 2023

Yes, this no longer creates an error. When sending FormData, there seem to be intermittent errors when sending (NetworkError, Socket closed) that don't seem to appear on iOS - but hard to say what's the exact issue, they also happen on 0.24. Might be something on my end.

@vladimirevstratov
Copy link

vladimirevstratov commented May 2, 2023

Thanks for previous answers, it also helps for me:

const decodedFileUri = decodeURIComponent(fileUri); 
// on Android is equal to
// file:///data/user/0/my.app/files/folder-id/filename.ext

const decodedFileName = decodeURIComponent(fileName);

const iosFileUri = decodedFileUri.replace('file:///', '/'); 

formData.append('objectId', objectId);
formData.append('file', {
-->  uri: Platform.OS === 'ios' ? iosFileUri : decodedFileUri,
  type: mimeType,
  name: decodedFileName,
});

@sergioisidoro
Copy link

Adding the mime type also worked for me. On iOS seems to not be needed.

@jvidalv
Copy link

jvidalv commented May 23, 2023

On iOS this was working fine, but on Android it was immediately failing without reaching the server with a "NETWORK ERROR".

I did have setup correctly in the headers multipart/form-data.

I didn't want to downgrade anything to fix this, if you are like ME this how I fixed it, my mixing @mateusfg7 and @pnxdxt solutions.

There are my relevant libraries:

    "axios": "^1.4.0",
    "expo": "~48.0.11",
    "react-native": "0.71.8",

And this is the code that I sent to my server:

import mime from "mime";

// Upload is the document that you receive from the file-picker library in Expo
const uri = Platform.select({
      ios: upload.uri.replace("file://", ""),
      android: upload.uri,
});
 
const file = {
        name: upload.name,
        type: mime.getType(uri),
        uri,
}   
    

After this, it has started working flawlessly without downgrading anything. Cheers!

@mohamed2m2018
Copy link

Solved my problem after adding headers content-type "multipart/form-data" instead of "x-www-form-urlencoded".

Axios version: 1.3.4

This worked with me

@mbachega
Copy link

I was having the same issue. Spent and entire day on it. Rolled back to Axios 0.24.0 and it started working.

This solved my problem too. thanks very much!

@iabdulhannan
Copy link

iabdulhannan commented Sep 18, 2023

React Native 0.72.4

Network Error on POST-ing FormData in Android disappeared by giving the following headers:

headers: {"content-type": "multipart/form-data"}

@alexkendall
Copy link

alexkendall commented Sep 20, 2023

Same issue here react-native 0.72.1

@vokecodes
Copy link

Rolled back to "axios": "^0.24.0" and it worked

@Kornelg96
Copy link

not working any of solution ; (

@Josh2941
Copy link

Josh2941 commented Oct 4, 2023

I was getting the same error. Spent several days and a lot of time upgrading packages and trying all the solutions from issues and stackoverflow. Finally this was the mistake which I don't think is mentioned which even in the docs.

If we have a FormData object

formData.append("name", "abc")
formData.append("state", undefined)
formData.append("address", {
    addressLine1: "",
    addressLine2: ""
});

It will throw the same error since the "state" is undefined and "address" is an object. But FormData accepts only string or File or Blob. So this was causing the issue for me. Once I replaced undefined with "" and "address" with JSON.stringify(addressObj) it started working.

Reference -> https://stackoverflow.com/a/72899049/5918233

@kararalzawaid
Copy link

for android you just need to set header
const headers = {
headers: {
'Content-Type': 'multipart/form-data',
}
};

  and added to your axios header call

@mironovpib101
Copy link

I getting this problem on Android from expo.
My search fail finished, but i fixed it!
My code:
image
I use mime on 65 line - no have result, and content-type dont help me on 74 line.
You need change http to https!
If json request running http on local development, "content-type": "multipart/form-data", required https!
Creating nginx virtual host and proxy to local api, this is working! good luck
PS. usesCleartextTraffic = false dont work :(

@vajid-khan
Copy link

vajid-khan commented Dec 22, 2023

I was able to fix the issue with below code
"axios": "^1.6.2"

const data = {}; //or FormData
const headers = {}; //your default headers

axios({
  url: "",
  method: "post",
  data: data,
  headers: {
    ...headers,
    ...(data instanceof FormData
      ? {
        "Content-type": "multipart/form-data"
      }
      : {})
    }
  });

@trantus
Copy link

trantus commented Jan 2, 2024

I have to send a request strongly without any Content-Type , so adding "Content-type": "multipart/form-data" isn't a solution for me

@Aszurar
Copy link

Aszurar commented Mar 4, 2024

2024, and I still have this problem, it doesn't happen every time, only sometimes and on Android.

As I said, it doesn't happen all the time, only once in a while, I haven't found a pattern for it.

I know that the file is filled, I have a log showing it before and in the request in the flipper the formData appears filled.

But out of nowhere, sometimes this network error happens, and when it happens, if you try to submit again, it works normally.

react native: 0.71.1
axios: 1.6.7

     console.log("file", file)
    const formData = new FormData();
    formData.append('file', file);

    return api.put<IBaseResponse<IOnboardingResponse>>(
      submitEvidenceRoute,
      formData,
      {
        headers: { 'Content-Type': 'multipart/form-data' },
      },
    );

I tried using mimo and the solutions above, but nothing... the worst thing is that it only happens once in a while, so I always have to test a lot to see if it solves it or not...

@Stargazer777777
Copy link

2024, and I still have this problem, it doesn't happen every time, only sometimes and on Android.

As I said, it doesn't happen all the time, only once in a while, I haven't found a pattern for it.

I know that the file is filled, I have a log showing it before and in the request in the flipper the formData appears filled.

But out of nowhere, sometimes this network error happens, and when it happens, if you try to submit again, it works normally.

react native: 0.71.1 axios: 1.6.7

     console.log("file", file)
    const formData = new FormData();
    formData.append('file', file);

    return api.put<IBaseResponse<IOnboardingResponse>>(
      submitEvidenceRoute,
      formData,
      {
        headers: { 'Content-Type': 'multipart/form-data' },
      },
    );

I tried using mimo and the solutions above, but nothing... the worst thing is that it only happens once in a while, so I always have to test a lot to see if it solves it or not...

You really save my day!

@Amatefinde
Copy link

oh, thanks a lot!
i am in middle of 2024 and they still don't fix it

I was having the same issue. Spent and entire day on it. Rolled back to Axios 0.24.0 and it started working.

@ashickantony
Copy link

2024, and I still have this problem, it doesn't happen every time, only sometimes and on Android.

As I said, it doesn't happen all the time, only once in a while, I haven't found a pattern for it.

I know that the file is filled, I have a log showing it before and in the request in the flipper the formData appears filled.

But out of nowhere, sometimes this network error happens, and when it happens, if you try to submit again, it works normally.

react native: 0.71.1 axios: 1.6.7

     console.log("file", file)
    const formData = new FormData();
    formData.append('file', file);

    return api.put<IBaseResponse<IOnboardingResponse>>(
      submitEvidenceRoute,
      formData,
      {
        headers: { 'Content-Type': 'multipart/form-data' },
      },
    );

I tried using mimo and the solutions above, but nothing... the worst thing is that it only happens once in a while, so I always have to test a lot to see if it solves it or not...

did you find any solution, same issue happening for me.

@boiboif
Copy link

boiboif commented May 24, 2024

same issue

@arashfallahi1989
Copy link

I faced exactly the same issue today and managed to address it by replacing the image type with 'image/jpeg'.

Old Code:

const data = new FormData();
data.append('image', {
  name: image.name,
  type: 'image',
  uri: image.path,
});

const response = await axios.post('/', data, {
  headers: {'content-type': 'multipart/form-data'},
});

New Code:

const data = new FormData();
data.append('image', {
  name: image.name,
  type: 'image/jpeg',
  uri: image.path,
});

const response = await axios.post('/', data, {
  headers: {'content-type': 'multipart/form-data'},
});

This solved the issue for me. Hope it helps!

@UdumiziSolomon
Copy link

UdumiziSolomon commented May 31, 2024

@arashfallahi1989
Still experiencing this issue
axios: ^1.7.2
expo: ~49.0.5
react-native: 0.72.10

This is the request body on Android
the uri = file:///data/user/0/x/cache/Print/70e29490-6cc7-499e-9567-ab2f08eacfdb.pdf

const body = new FormData();
 body.append('title', item?.title);
 body.append('document', {
   uri: uri,
   name: item?.title,
   type: mime.getType(uri),
 });

this is the axios request

export const useSendDocument = () => {
  return useMutation(
    async (body: any) => {
      const { data } = await SERVER.post(
        `/xxx/send-document`,
        body,
        {
          headers: {
            'Content-Type': 'multipart/form-data',
          },
        },
      );
      return data;
    },
    {
      onError: (error: AxiosError) => {
        handleAxiosError(error);
      },
    },
  );
};

I keep getting 'Network Error' on Android, works well for IOS and also NB: every 1 out of 50 request sent on Android works. Any help would be appreciated.

@boiboif
Copy link

boiboif commented Jun 1, 2024

Try update axios version to latest and use fetch as adaptor. It work for me. I have tried 100 times formData post requests in a row without "network error".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests