Expo应用Fetch请求npm run web运行正常但手机端报错问题咨询
问题触发原因
- 核心问题出在Fetch请求的地址写死了
localhost:9000:localhost指向的是当前运行设备的本地地址,web端运行时浏览器和后端服务都在你的电脑上,所以可以正常访问;但手机端运行时localhost指向的是手机本身的本地端口,你的手机上并没有运行对应9000端口的后端服务,自然会触发请求失败报错。 - 次要兼容问题:代码中使用了
window.alert,window对象是浏览器专属API,Expo手机端运行环境中不存在window对象,调用时也会抛出异常。 - 潜在逻辑问题:代码混用了
async/await和.then异步写法,同时没有处理res.ok为false的异常情况,非200状态的响应不会被catch捕获,会引发预期外的报错。
解决方案
- 第一步:替换请求地址为你电脑的局域网IP地址
首先查看你开发电脑的局域网IP(Windows可以在cmd执行ipconfig,Mac/Linux执行ifconfig或者ip addr,一般是192.168开头的地址),将fetch地址修改为http://你的局域网IP:9000/customer-registration,同时要保证你的手机和电脑连接的是同一个WiFi,处在同一个局域网下。 - 第二步:替换
window.alert为Expo兼容的提示组件
使用React Native自带的AlertAPI,先引入:import { Alert } from 'react-native',然后把所有的window.alert/alert都替换为Alert.alert。 - 第三步:优化异步请求逻辑,补全异常处理
优化后的参考代码如下:
const onSubmit = async (e) => { e.preventDefault(); console.log(fullname1, email1, password1, address1, phone1); const fullname = fullname1; const email = email1; const password = password1; const address = address1; const phone = phone1; // 校验空值 if (!fullname || !email || !password || !address || !phone) { Alert.alert("提示", "输入字段不能为空"); return; } try { // 注意替换为你自己的电脑局域网IP const res = await fetch("http://192.168.xxx.xxx:9000/customer-registration", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ fullname, email, password, address, phone, }), }); if (!res.ok) { throw new Error(`请求错误,状态码:${res.status}`); } const data = await res.json(); if (data.empty === "true") { Alert.alert("提示", "输入字段不能为空"); } else if (data.flag === "true") { Alert.alert("提示", "邮箱已存在"); } else { Alert.alert("提示", "客户注册成功"); } } catch (error) { Alert.alert("提示", "注册失败"); console.log(error); } };
- 第四步:如果是Android设备,还需要额外配置允许明文HTTP请求:在app.json的expo.android配置项中添加
"usesCleartextTraffic": true,避免Android高版本默认禁止HTTP请求导致的访问失败。
内容的提问来源于stack exchange,提问作者Shahzeb Ali
相关产品推荐
相关产品推荐

