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项目中添加自定义网络安全配置:
- 在项目根目录创建
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>
- 在
app.json的android字段中引用该配置:
"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_LOCATION、ACCESS_FINE_LOCATION、CAMERA都是危险权限,Android 6.0+(包括Android 10)要求必须动态请求这些权限,只在配置文件里声明是没用的:
- 安装对应的Expo权限相关库:
expo install expo-location expo-camera
(位置权限依赖expo-location,相机权限依赖expo-camera,它们内部已经封装了权限请求逻辑)
- 在应用启动或需要使用权限的时机,添加动态请求代码:
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




