React Native通过Fetch进行的Post请求抛出了“网络请求失败”的错误。

34

我遇到了以下错误。 目前我正在使用React Native开发Android应用程序,因此我计划使用fetch来为我执行POST请求。

fetch("https://XXreachable-domainXX.de/api/test", {
    method: "post",

    body: JSON.stringify({
      param: 'param',
      param1: 'param',

    })
  })
  .then((response) = > response.json())
  .then((responseData) = > {
    ToastAndroid.show(
      "Response Body -> " + JSON.stringify(responseData.message), ToastAndroid.SHORT
    )
  })
  .catch((error) = > {
    console.warn(error);
  });

该应用现在抛出一个错误:

类型错误:网络请求失败

当我将代码更改为GET请求时,它可以正常工作,在浏览器上使用window.alert()作为返回也很好,Chrome扩展程序Postman也能正确返回数据。


请参考以下链接: https://github.com/facebook/react-native/issues/5222#issuecomment-170239302 - sachin1
3
如果在iOS上遇到这个问题,请确保使用的是https而非http。默认设置只支持https。 - wuliwong
如何更改设置以支持HTTP? - MadPhysicist
你需要在 info.plist 中批准域名。https://dev59.com/oloT5IYBdhLWcg3wlgPn - nicholas
即使没有联网,在屏幕上显示“网络请求失败”的红色界面也不太美观,有没有一种可以自定义处理的方式,例如弹出警告框或其他方法。 - akaMahesh
11个回答

15

开发Windows OS/PHP内置服务器/react-native Android设备:

  • 检查本地服务器IP地址(ipconfig),例如172.16.0.10
  • 在react-native的fetch中使用此URL和适当的端口(fetch('http://172.16.0.10:8000/api/foo)
  • 使用此特定IP而不是本地主机运行PHP内置服务器:php -S 172.16.0.10:8000 ...
  • 关闭Windows防火墙,以供私有网络使用

这解决了我手机与本地服务器之间的连接问题。


只需将“localhost”替换为我的本地IP即可解决问题,也许是解析“localhost”的错误? - xHocquet

15

React Native的错误信息比较无用,所以您需要首先获取实际的基础错误。最直接的方法是编写一个小型本地程序,该程序将仅使用HttpsURLConnection执行相同的查询。

对于我来说,实际的错误是java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.这个错误有一个众所周知的解决方法:https://developer.android.com/training/articles/security-ssl.html#MissingCa

鉴于浏览器和Postman没有问题,这很可能也是您的情况。要检查它,请运行openssl s_client -connect XXreachable-domainXX.de:443 -showcerts。如果存在证书错误,请先修复它们,这可以为您节省编写本地程序的时间。

编辑:实际上,查看React Native所有基础Android错误的最简单方法只是在终端中运行“adb logcat”。


14

其他答案都没有帮助到我。 问题出在headers上:

旧的头部:

fetch(API_HOST, {
                method: 'POST',
                headers: {
                    Accept: 'application/json'
                },
                body: JSON.stringify(data),

更新的页眉:

fetch(config.API_HOST, {
                method: 'POST',
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json'  // I added this line
                },
                body: JSON.stringify(data),

遇到了同样的问题。这个解决了!谢谢。 - Costin
太棒了,捕捉成功...你救了我的一天。谢谢!做得好。 - Mohammad nabil

6
如果你遇到了这个错误,并且确定一切正常,同时你正在运行模拟器,请关闭模拟器并重新启动它。这样应该就可以解决问题了。
通常情况下,这种情况发生在你的系统休眠一段时间后。

2

步骤1> 在AndroidManifest.xml文件中添加android:usesCleartextTraffic="true"行,如下所示:

// 添加这一行 ... 步骤2> 从您的android文件夹中删除所有debug文件夹。


从API级别28开始,默认值为false。如果您想使用HTTP(而不是HTTPS),则需要将其设置为true。帮了我一个大忙--谢谢! - Deco

0

我在使用fetch时遇到了同样的问题,这是一种类型错误。尝试使用Axios。这对我有用。

之前不起作用的代码:error:[typeError : network Request failed]

return fetch(addProduceApi, { method: 'PATCH', body: bodyParamData, headers: getAuthHeader() })
.then((response: any) => response.json()) .catch((error: any) => console.log('Error in patchProduce: ', error));

工作代码:

return axios.patch(addProduceApi,produceData,{ headers: getAuthHeader()}) 

.then((response: any) => response.json()) .catch((error: any) => console.log('Error in patchProduce: ', error));?

0

当我重启模拟器后,我的问题得到了解决


0
如果你在模拟器上遇到这个问题,确保你也在设备上进行测试。很可能是不会在设备上出现这个问题。
只要你能解决这个问题,就没什么好担心的。

0

我在Android上遇到了由于证书过期而引起的问题。 我收到的错误消息是com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException:无法验证证书:证书已于2017年9月29日星期五16:33:39 EDT过期(与2017年12月8日14:10:58 EST相比)

我能够使用digicert.com确认这一点。

不幸的是,我确实不得不深入研究React Native代码,并调试捆绑包中的XHR代码(index.android.bundle),以找到错误消息和相关的URL,因为它在我的某些日志记录代码中,显然我没有将其记录到控制台中。 :)

这个GitHub问题评论帮助了我。


0

我在安卓模拟器上遇到了一个重大问题。在iOS上,需要在info.plist中批准域名。明确一下,我试图登录我的.NET Web托管API。

解决方法是确保POST数据被参数化。(我很确定这是一个词)

export const loginUser = ({ userName, password }) => {
const data = `UserName=${userName}&Password=${password}&grant_type=password`
    return (dispatch) => {
        dispatch({ type: LOGIN_USER })

        fetch(URL_LOGIN, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: data
            // body: {

            //     UserName: userName,
            //     Password: password,
            //     grant_type: 'password'

            // }

        })
            .then((response) => { 
                loginUserSuccess(dispatch, response)
            })
            .catch((response) => {
                loginUserFailed(dispatch, response)
            })
    };
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接