React Native Android Fetch 在连接到本地 API 时失败
Posted
技术标签:
【中文标题】React Native Android Fetch 在连接到本地 API 时失败【英文标题】:React Native Android Fetch failing on connection to local API 【发布时间】:2016-02-15 16:57:51 【问题描述】:我在我的 react-native android 应用中使用 fetch API 向本地 API 发出请求。我通常在 http://localhost:8163 从 react web 应用程序中查询上述 API。
我正在我的物理设备上以调试器模式测试我的应用程序。我在某处读到 react-native 无法像 Web 应用程序那样查询 localhost。显然你必须使用http://10.0.2.2:[PORT_NUMBER_HERE]/
,它是根据Android emulator docks 的`http://127.0.0.1:[PORT_NUMBER_HERE] 的别名。我不确定这是否是我在物理设备上测试时应该做的。
我的获取代码如下所示:
fetchToken()
fetch('http://10.0.2.2:8163/extension/auth',
method: 'GET',
headers:
'Accept': 'application/json',
'Content-type': 'application/json'
)
.then((response)) => console.log('successful fetchToken response: ', response.json()))
.catch((error) => console.log('fetchToken error: ', error))
.done();
请求总是挂起一段时间,然后到达catch
块,并出现无用的错误TypeError: Network request failed(...)
。检查我的本地 API 的日志,他们根本没有注册请求。
所以我不知道我是否正确查询本地 API 以获取我想要的资源,如果是,我不知道为什么获取失败。
【问题讨论】:
是的,那是因为您的 android 模拟器与本地开发计算机不同。对于物理设备,这就像在不同的机器上进行测试一样:要么拥有名称解析系统,要么使用 IP 地址 @njzk2 你能详细说明一下吗?我有同样的问题,但不确定名称解析系统是什么意思?我按照 react-native 文档中的要求使用计算机的 IP 地址.. @Andrea.cabral 名称解析通常由 DNS 完成。 你解决了吗? 【参考方案1】:您无法访问本地开发服务器,因为 ADB 尚未转发该端口。当你运行 react-native run-android
时,React Native 将端口 8081 映射到 USB 上的移动设备。当您断开 USB 时,您将无法再刷新或热重载您的代码。所以在这种情况下你可以做两件事,要么像 React Native 那样映射你的本地服务器端口,要么使用你的本地 IP 地址。
映射端口
这仅在您使用 Android 6.0+ 时有效。要使用 ADB 转发端口,请在终端中运行以下命令:
adb reverse tcp:8163 tcp:8163
这会将您本地的8163
端口映射到手机的8163
端口。您将能够通过这种方式访问您的开发服务器。
使用本地 IP 地址
您还可以在 React Native 开发应用程序上使用本地 IP 来重新加载它们而无需 USB。摇动您的设备或长按菜单按钮以打开开发者菜单。打开Dev Settings
,然后点击Debug server host & port for device
。在这里你可以输入你机器的本地 IP 和端口号8081
。例如。如果您的机器的 IP 是 192.168.1.100
,那么您将在此处输入 192.168.1.100:8081
以成功连接。现在我们已经介绍了我们可以重新加载应用程序。在此之后,当您想使用本地计算机的开发服务器时,请使用与服务器端口号相同的 IP。
你应该很好。
【讨论】:
非常感谢您! adb反向救了我!起初我认为这是一个 http 与 https 的事情,并花了很长时间试图弄清楚如何设置我的 localhost API 以使用 https 而不是 http,结果一直都是这样。我不知道为什么我没有想到我的设备(即使它在模拟器中运行)默认情况下无法连接到我电脑上的 localhost:port。 解决方案 1:不适合我 解决方案 2:不适合我可怜的我! 我遇到了 ngrok。这是一个伟大的转发。一直在用它把我的本地 web api 暴露给外界。 我为此困惑了好几天。不明白为什么我的应用程序会在8081
上从 Metro 加载然后失败 request'n dev server @3000
模拟器的互联网似乎可以工作,但在登录时不在应用程序中。花了 40 多个小时,整整一周的工作,在各种方法上。我什至一度愚蠢地尝试adb reverse tcp:8081 tcp:8081
,它会中断与捆绑器的连接,但直到我读到你说的地方我才连接点:[on]react-native run-android
,React Native 将端口 8081 映射为USB 上的移动设备 非常感谢。对我来说adb reverse tcp:3000 tcp:3000
和繁荣。 ?
解决方案 1 非常适合我。你用 Jason-proxy 和其他变通方法等不同的东西为我节省了 2 个小时的测试时间,谢谢!【参考方案2】:
运行以下命令访问 localhost 或 127.0.0.1 或您计算机的 ip
adb -s <device_name> reverse tcp:backend_port tcp:backend_port
例子:
adb -s emulator-5554 reverse tcp:3000 tcp:3000
现在,您可以在组件中使用如下所示。
import React from 'react';
import View,Image,TextInput, TouchableOpacity, StyleSheet, ImageBackground, AsyncStorage from 'react-native';
import Text,Button from 'native-base';
export class Login extends React.Component
constructor(props)
super(props);
this.state=username:'',password:''
login = () =>
fetch('http://localhost:3000/users',
method:'POST',
headers:
'Accept':'application/json',
'Content-Type':'application/json'
,
body:JSON.stringify(
username:this.state.username,
password:this.state.password
)
)
.then((response)=>response.json())
.then((res)=>
if(res.success===true)
var username=res.message;
AsyncStorage.setItem('username',username);
this.props.navigation.navigate('app');
alert("Login success");
else
alert("Invalid Credentials");
)
.done();
render()
return (
<View style=styles.content>
<Text style=styles.logo>- WELCOME -</Text>
<View>
<TextInput underlineColorAndroid='transparent' style=styles.input placeholder="Username"
onChangeText=(username)=>this.setState(username)
value=this.state.username>
</TextInput>
<TextInput secureTextEntry=true underlineColorAndroid='transparent' style=styles.input placeholder="Password"
onChangeText=(password)=>this.setState(password)
value=this.state.password>
</TextInput>
</View>
<TouchableOpacity onPress=this.login style=styles.buttonContainer>
<Text style=styles.buttonText>LOGIN</Text>
</TouchableOpacity>
</View>
);
const styles = StyleSheet.create(
container:
flex:1,
,
content:
opacity:0.9,
backgroundColor:'white',
borderWidth:2,
margin:10,
alignItems: 'center',
,
logo:
justifyContent: 'center',
alignItems: 'center',
fontSize:45,
color:'black',
textShadowColor:'gray',
textShadowRadius:10
,
input:
borderRadius:10,
padding:10,
color:'black',
borderWidth:2,
borderColor:'lightgray',
width:200,
margin:5
,
buttonContainer:
margin:10,
padding:10,
justifyContent: 'center',
alignItems: 'center',
,
buttonText:
borderRadius:100,
padding:10,
backgroundColor:'magenta',
color:'white',
textAlign:'center',
width:100
);
输出:
【讨论】:
使用 127.0.0.1:8081 很重要,否则会抛出错误 如果该端口已经在使用中会报错,否则不会报错。我只在linux中试过。所以,不知道windows还是mac。 像魅力一样工作!!!【参考方案3】:就我而言,我尝试使用 axios 向 http://localhost:3000
发出请求,但每次我收到 Network Error
作为响应。然后我发现如果是android模拟器,我需要向http://10.0.2.2:3000
提出请求。对于 iOS 模拟器,它适用于 http://localhost:3000
。
结论
使用
http://10.0.2.2:3000
而不是
http://localhost:3000
更新
更好的选择是将计算机的本地服务器端口映射到设备中的相同端口
-
查看已连接设备列表。可以是模拟器也可以是真机
$ adb devices
List of devices attached
emulator-5554 device <--- emulator
2681523e device <-- real device
-
映射端口
$ adb -s emulator-5554 reverse tcp:3000 tcp:3000
$ adb -s 2681572e reverse tcp:3000 tcp:3000
你已经完成了。
【讨论】:
对我来说工作是一种简单而快速的解决方案,我只需要用我的后端端口更改端口。谢谢,兄弟【参考方案4】:http or https based on it copy the URL
第一步:下载ngrok解压包
第2步:打开ngrok.exe安装它(或)双击它终端将打开
第 3 步:
ngrok http (port no of backend services)
eg:ngrok http 8081
第 4 步:如果是 https,则复制 https 的 url,然后将其粘贴到 UI 中的 URL 位置。
【讨论】:
【参考方案5】:在桌面打开控制台,输入:ipconfig
你会得到一个 IPv4_Address
试试这个:'http://IPv4_Address:8163/extension/auth'
【讨论】:
用法:ipconfig美好的一天, 这是有效的
我使用我机器的IP以太网适配器Ethernet 2:IPV4地址
并允许我的端口在防火墙上的入站和出站规则
【讨论】:
【参考方案7】:如果您在 Expo Developer Tools 中使用 Metro Bundler 使用 CONNECTION LAN ip 地址 Sample image Metro Bundler
如何在 react native 中使用
getfetch = () =>
return fetch('http://LAN-IP-ADDRESS-HERE:4300/customers/',
method: 'GET',
headers:
Accept: 'application/json',
'Content-Type': 'application/json',
)
.then((response) => response.json())
.then((responseJson) =>
console.log(responseJson);
)
.catch((error) =>
console.error(error);
);
使用邮递员的示例图像 REST API
Sample image POSTMAN
希望这会有所帮助:)
【讨论】:
【参考方案8】:我遇到了同样的问题,这个解决方案对我有用:-
第 1 步:通过在终端中输入 ipconfig
获取您的 IpV4 地址
第 2 步:将您的 API 托管在您的 IpV4 地址而不是 localhost(例如:-192.168.0.106:3000
)
第 3 步:首先运行您的 API
第四步:从新地址获取数据(例如:-192.168.0.106:3000
)
第 5 步:然后才使用 react-native start 或 npm start 启动您的应用
【讨论】:
用法:ipconfig遇到相同/相似的问题 - 我花了整整两天时间才解决它。我使用带有 Visual Studio Code 的 Win10 机器、附加的 Android 设备和用于 API 的本地 php 服务器。也许这会对某人有所帮助:
-
电缆 -> 尝试不同的 USB 电缆,在我的 3 根电缆中只有一根可以使用
连接模式 -> 非常重要,我必须选择 PTP 模式才能使其工作
同一个网络 -> 手机和电脑必须在同一个网络
私网 -> 网络必须是私网,公网不行
IP -> 在 PowerShell 中运行 ipconfig 并获取您的 IP4 地址
防火墙 -> 接受防火墙提示
PHP 服务器 -> 使用 "php -S your IP:8081" 启动内置 PHP 服务器
测试 PHP 服务器 -> 创建 index.php 并在手机上打开 your IP:8081
获取 -> 创建获取脚本(示例如下)
fetch('http://your IP:8081/')
.then((response) => response.json())
.then((responseJson) =>
this.setState( message : responseJson.message.data )
)
.catch((error) =>
console.error(error);
);
【讨论】:
【参考方案10】:如果您使用 expo,只需复制 QR 码上方的 URL 并将其添加到您的 API 而不是 localhost
会这样的
expo host :http://192.168.0.109:Your Port/The name for your API
【讨论】:
【参考方案11】:尝试使用127.0.0.1
主机。
它对我有用。
【讨论】:
【参考方案12】:也许我的建议迟到了,但这对我有帮助。
你应该试试http://0.0.0.0:8163/extension/auth
【讨论】:
以上是关于React Native Android Fetch 在连接到本地 API 时失败的主要内容,如果未能解决你的问题,请参考以下文章
React Native Android - 第一次运行 react-native run-android 时出错
React Native - 在 Android 上构建 react-native-camera 错误
使用 react-native run-android 运行时出现 React-Native 错误
react-native run-android上的React Native错误
解决 React-Native: Android project not found. Maybe run react-native android first?
React Native 项目 Android Gradle 失败(React-Native-Reanimated Fail)