You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Expo项目Android端POST请求报错:Unhandled promise rejection

解决Expo Android端Network Request Failed及权限未请求问题

先帮你梳理下两个核心问题的排查和解决思路,我之前也踩过类似的坑,咱们一步步来:

一、Network Request Failed 网络请求失败问题

你的代码在iOS和Web端正常跑通,说明接口本身没问题,Android端的请求失败大概率是平台特有的限制或配置问题,试试下面几个方案:

1. 检查HTTPS证书有效性

Android对HTTPS证书的校验比iOS严格得多,如果你的服务器用的是自签名证书、证书过期或者证书链不完整,都会直接导致fetch请求失败。

  • 临时测试:如果服务器允许,把请求URL改成HTTP(注意Expo开发环境下HTTP需要额外配置,生产构建则要在网络安全配置里允许),看看能不能正常请求,以此排除证书问题。
  • 正式解决:确保服务器的HTTPS证书是正规CA签发的,并且证书链完整(可以用在线证书检测工具确认状态)。

2. 调整请求Header

你当前请求里加了Accept-Encoding: gzip,deflate,部分Android版本的fetch对这个header的处理可能存在兼容问题,建议先移除这个header试试:

_userLogin() {
  let username = this.state.username;
  let password = this.state.password;
  fetch("https://domain/login-react", {
    method: "POST",
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
      // 移除Accept-Encoding header
    },
    body: JSON.stringify({
      username: username,
      password: password,
    }),
  })
  .then((response) => response.json())
  .then((responseData) => {
    // 原有逻辑不变
  })
  .catch(error => {
    console.error('请求错误详情:', error);
    alert('请求失败: ' + error.message);
  })
}

3. 添加Android网络安全配置

如果你的服务器有特殊网络配置(比如使用内部CA、需要允许特定域名的明文请求),可以在Expo项目中添加自定义网络安全配置:

  1. 在项目根目录创建android/app/src/main/res/xml/network_security_config.xml(目录不存在就手动创建),内容如下:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <!-- 如果是自签名证书,可添加下面一行并替换为你的证书路径 -->
            <!-- <certificates src="@raw/your_certificate" /> -->
        </trust-anchors>
    </base-config>
</network-security-config>
  1. app.jsonandroid字段中引用该配置:
"android": {
  "permissions" : ["ACCESS_COARSE_LOCATION", "ACCESS_FINE_LOCATION", "CAMERA", "INTERNET"],
  "adaptiveIcon": {
    "foregroundImage": "./assets/adaptive-icon.png",
    "backgroundColor": "#FFFFFF"
  },
  "package": "app.htgps.listare",
  "networkSecurityConfig": "./android/app/src/main/res/xml/network_security_config.xml"
},

4. 捕获详细错误信息

当前错误只显示了笼统的“Network request failed”,建议在fetch的catch块里打印详细错误,方便精准定位:

fetch(...)
.then(...)
.catch(error => {
  console.error('请求错误详情:', error);
  alert('请求失败: ' + error.message);
})

二、Android 10设备未请求权限问题

你在app.json里配置的ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATIONCAMERA都是危险权限,Android 6.0+(包括Android 10)要求必须动态请求这些权限,只在配置文件里声明是没用的:

  1. 安装对应的Expo权限相关库:
expo install expo-location expo-camera

(位置权限依赖expo-location,相机权限依赖expo-camera,它们内部已经封装了权限请求逻辑)

  1. 在应用启动或需要使用权限的时机,添加动态请求代码:
import * as Location from 'expo-location';
import * as Camera from 'expo-camera';

// 组件挂载时请求权限
async componentDidMount() {
  // 请求位置权限
  const locationPermission = await Location.requestForegroundPermissionsAsync();
  if (locationPermission.status !== 'granted') {
    alert('需要位置权限才能使用相关功能');
  }

  // 请求相机权限
  const cameraPermission = await Camera.requestCameraPermissionsAsync();
  if (cameraPermission.status !== 'granted') {
    alert('需要相机权限才能使用相关功能');
  }
}

这样应用启动后就会弹出权限请求对话框,用户授权后才能使用对应功能。

额外提示

如果以上方案都没解决,还可以试试:

  • 检查Android设备的网络状态,有没有代理、VPN等干扰网络连接的设置;
  • expo diagnostics命令查看项目环境信息,确认Expo SDK版本和Android编译环境是否兼容;
  • 创建一个最小化测试项目,只保留fetch请求代码,排查是否是项目中其他代码的干扰。

内容的提问来源于stack exchange,提问作者FunkyRabbiteroo

火山引擎 最新活动