Capacitor on iOS: POST request fails

Viewed 4158

I'm using Ionic (v5) + React + Capacitor to create an app for iOS and I recently got stuck with a really strange error: fetch() and axios successfully perform GET requests to the backend while POST requests are always failing.

fetch() returns "cancelled" which tells me nothing but a failure meanwhile axios generates a more descriptive error:

{
  "message": "Network Error",
  "name": "Error",
  "stack": "capacitor://localhost/static/js/8.98344607.chunk.js:2:168604\ncapacitor://localhost/static/js/8.98344607.chunk.js:2:167548",
  "config": {
    "url": "auth",
    "method": "post",
    "data": "{\"email\":\"email-here\",\"password\":\"111111\"}",
    "headers": {
      "Accept": "application/json",
      "Content-Type": "application/json"
    },
    "baseURL": "https://website.com/api/1.3/",
    "transformRequest": [
      null
    ],
    "transformResponse": [
      null
    ],
    "timeout": 0,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1
  }
}

Already checked Apache's CORS settings, it should be OK. Could anyone suggest a fix for this?

Upd.1: part of my code that performs all api requests

const axConf: AxiosRequestConfig = {
    url: query, // string
    method: m, // string
    baseURL: global.base_uri + 'api/' + global.api_version + '/',
    headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
    },
    data: r, // object
    validateStatus: function (status) { return status >= 200 && status < 300; }
};
return new Promise(resolve => {
    axios(axConf)
        .then(response => resolve(successRes(r, i, response.data)))
        .catch(function (error) {
                console.log(error);
                if (error.response) {
                    resolve(errorRes(i, error.response));
                } else if (error.request) {
                    resolve(errorRes(i, error.request));
                } else {
                    resolve(errorRes(i, error.message));
                }
            }
        );
});
3 Answers

Finally, after couple of days trying to solve this problem I found the solution. Here it is, for everyone struggling with this:

This error happens when you try to perform a HTTP request and then something in your code breaks this request. In my case that was the form: my fetch() request has been triggered by button's onClick action with type="submit" set on it and submitting the form itself triggered nothing but a state update which has been cancelling my request.

I was switching my app from Ionic v4 & Angular to Ionic v5 & React and previously the form didn't cause such behavior that's why I didn't even think this might be a thing.

I just removed onClick action from my button and set onSubmit={handleLogin} to the form itself. Then modified the code like this:

const handleLogin = (e: FormEvent) => {
    fnGetUserToken(loginData).then(...);
    e.preventDefault();
};

Note the e.preventDefault(); at the end.

In case you can not alter your code like this, I guess you could try to remove the property type="submit" from your button.

Another answer that led me to this solution.

For me it was not having the url of my API in capacitor.config. So make sure

  1. Your API is SSL-secured
  2. You send Access-Control-Allow-Origin header in the response of your API (you have to add either capacitor://localhost or ionic://localhost)
  3. Your capacitor.config (or capacitor.config.json in case you use quasar) looks like
{
  ...,
  "server": {
    "allowNavigation": [
      "path.to-your-api.com"
    ]
  }
}
Related