iOS 上的电容器:POST 请求失败

Capacitor on iOS: POST request fails

我正在使用 Ionic (v5) + React + Capacitor 为 iOS 创建一个应用程序,我最近遇到了一个非常奇怪的错误:fetch() 和 axios 成功地向后端执行 GET 请求而 POST 请求总是失败。

fetch() returns "cancelled" 除了失败什么也没告诉我,同时 axios 生成了一个更具描述性的错误:

{
  "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
  }
}

已经检查过Apache的CORS设置,应该没问题。有人可以建议解决这个问题吗?

Upd.1:执行所有 api 请求的部分代码

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));
                }
            }
        );
});

终于,在尝试解决这个问题几天后我找到了解决方案。 在这里,对于所有为此苦苦挣扎的人:

当您尝试执行 HTTP 请求然后您的代码中的某些内容中断了该请求时,就会发生此错误。 在我的例子中是表单:我的 fetch() 请求是由按钮的 onClick 操作触发的,上面设置了 type="submit" 并且提交表单本身只触发了一个状态更新,它一直在取消我的请求。

我正在将我的应用程序从 Ionic v4 和 Angular 切换到 Ionic v5 和 React,之前的表单不会导致这种行为,这就是为什么我什至不认为这可能是一件事。

我刚刚从我的按钮中删除了 onClick 操作并将 onSubmit={handleLogin} 设置为表单本身。然后修改代码如下:

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

注意最后的e.preventDefault();

如果您不能像这样更改代码,我想您可以尝试从按钮中删除 属性 type="submit"

Another answer 这让我想到了这个解决方案。

我花了几天时间解决这个问题。结果:javascript 调用在离子和电容器中存在 CORS 问题,因此您需要 运行 本机调用,尤其是在 IOS 中才能工作。

有关此内容的完整博客文章可在此处找到: https://enappd.com/blog/how-to-make-api-calls-in-ionic-capacitor-apps/179/#66d6

终于解决了我的问题

对我来说,capacitor.config 中没有我的 API 的 url。所以确保

  1. 你的 API 是 SSL-secured
  2. 您在 API 的回复中发送 Access-Control-Allow-Origin header(您必须添加 capacitor://localhostionic://localhost
  3. 你的 capacitor.config(或 capacitor.config.json,如果你使用类星体)看起来像
{
  ...,
  "server": {
    "allowNavigation": [
      "path.to-your-api.com"
    ]
  }
}