React Native fetch请求在安卓上总是失败怎么办?

东方文君 阅读 31

我在安卓真机测试时,用fetch('https://api.example.com/data')请求老是报错“Network request failed”,iOS模拟器却能正常获取数据。已经试过加credentials: 'include'和检查AndroidManifest.xml里的互联网权限,还是不行。

代码是这样的:


try {
  const response = await fetch(url);
  return await response.json();
} catch (error) {
  console.error('请求失败:', error);
}

日志只显示网络错误,抓包工具也看不到请求发出,是不是安卓有特殊配置?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
极客国曼
这问题我见过好几次了,基本就是安卓的网络安全策略在搞鬼。iOS随便请求,安卓从9开始默认禁止明文流量,但你用的是 https,所以不是这个原因——重点在于安卓的 TLS 配置可能不兼容服务端的证书链。

先调试看看:把 fetch 换成 fetch(url, { mode: 'no-cors' }) 试一下,如果报错变成 opaque response,说明请求确实发出去了,只是返回拿不到——这大概率是 TLS 握手失败。

真机上直接用 WebView 打开同一个 URL,看浏览器有没有安全警告,比如“您的连接不是私密连接”那种。如果有,说明服务端证书有问题,安卓拒绝握手了。

常见解决方案有三个:

1. 如果是测试环境,最省事的是让后端把证书链补全,尤其是中间证书,很多自签名或者 Let’s Encrypt 的链没配好,安卓老版本认不了

2. 临时调试可以用 react-native-ssl-pinning 绕过证书校验,但别上生产,代码示例:

import SslPinning from 'react-native-ssl-pinning';

const response = await SslPinning.fetch('GET', url, {
headers: { 'Content-Type': 'application/json' },
sslPinning: {
cert: 'YOUR_CERT_BASE64', // 或者用 .pem 文件路径
},
});


3. 如果是自己控制的后端,确认 TLS 版本至少支持 TLS1.2,安卓5.0以下默认只支持到 TLS1.0,不过现在基本没人测 5.0 了。

最后说个坑:有些公司内网接口用的是自签名证书,安卓会直接断开连接,抓包工具也看不到请求——因为连 TCP 握手都没过去。这时候必须加证书信任配置,或者换正式证书。

你先试试用浏览器打开那个 API 地址,看看有没有安全提示,这一步能快速定位是不是证书问题。
点赞 7
2026-02-25 23:08
Dev · 锦玉
这个问题八成是安卓的网络安全配置问题。从 Android 9(Pie)开始,默认不允许明文 HTTP 请求,但其实 HTTPS 在某些情况下也会被拦截,尤其是调试时用了自签名证书或者本地代理。

你虽然加了互联网权限,但还得检查一下 android/app/src/main/res/xml/network_security_config.xml 文件有没有配置信任你的域名或允许明文流量。

先在 android/app/src/main/AndroidManifest.xmlapplication 标签里加上:

<application
...
android:networkSecurityConfig="@xml/network_security_config">


然后在 res/xml 目录下创建 network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">api.example.com</domain>
</domain-config>
</network-security-config>


这样至少能先跑通。线上环境记得关掉 cleartextTrafficPermitted,只保留必要的域名。

另外 fetch 可以优化成更健壮一点的写法,避免因为默认配置导致跨域或 cookie 问题:

const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include', // 如果需要携带 cookie
});


最后,真机测试时别忘了时间同步问题,系统时间不准也会导致 HTTPS 握手失败,我就踩过这坑。抓不到包很可能请求根本没发出去,先确保网络层放行再说。
点赞 7
2026-02-11 00:08