响应本地Android获取在连接到本地API时失败
我在react原生Android应用程序中使用FetchAPI向本地API发出请求。我通常从react web apps的http://localhost:8163. 我正在调试模式下在物理设备上测试我的应用程序。我在某个地方读到,react native无法像web应用程序一样查询localhost。显然,您必须使用响应本地Android获取在连接到本地API时失败,android,react-native,Android,React Native,我在react原生Android应用程序中使用FetchAPI向本地API发出请求。我通常从react web apps的http://localhost:8163. 我正在调试模式下在物理设备上测试我的应用程序。我在某个地方读到,react native无法像web应用程序一样查询localhost。显然,您必须使用http://10.0.2.2:[PORT\u NUMBER\u HERE]/是的别名`http://127.0.0.1:根据Android仿真器码头的数据,这里有[端口号]。我不
http://10.0.2.2:[PORT\u NUMBER\u HERE]/
是的别名`http://127.0.0.1:根据Android仿真器码头的数据,这里有[端口号]。我不确定这是否是我在物理设备上测试时应该做的
我的获取代码如下所示:
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:networkrequest失败(…)
。检查本地API的日志,他们根本不注册请求
因此,我不知道是否正确查询本地API以获取所需的资源,如果是,我不知道获取失败的原因。您无法访问本地开发服务器,因为该端口尚未由ADB转发。当您运行
react native run android
时,react native会将端口8081映射到USB上的移动设备。当您断开USB连接时,您将无法再刷新或热重新加载代码。因此,在这种情况下,您可以做两件事,要么像React Native一样映射本地服务器端口,要么使用本地IP地址
adb reverse tcp:8163 tcp:8163
这将把您的本地8163
端口映射到手机的8163
端口。您将能够通过这种方式访问您的开发服务器开发设置
,然后点击调试设备的服务器主机和端口
。在这里,您可以输入机器的本地IP,端口号为8081
。例如,如果您的机器的IP为192.168.1.100
,则您需要在此处输入192.168.1.100:8081
,以便成功连接。现在我们已经讨论了可以重新加载应用程序的问题。之后,当您想使用本地计算机的开发服务器时,请使用与服务器端口号相同的IP你应该很乐意这样做。有同样/类似的问题-我花了整整两天的时间才解决。我使用一台带有VisualStudio代码的Win10机器、连接的Android设备和一个本地PHP服务器作为API。也许这会对某人有所帮助:
fetch('http://{your-IP}:8081/'))
.then((response)=>response.json())
.然后((responseJson)=>{
this.setState({message:responseJson.message.data})
})
.catch((错误)=>{
控制台错误(error);
}); 代码>
如果您在Expo开发者工具中使用Metro Bundler
使用连接LAN ip地址
如何在react native中使用
使用postman的示例图像RESTAPI
希望这会有所帮助:)
也许我提建议迟到了,但这对我有帮助
您应该尝试运行以下命令来访问localhost或127.0.0.1或您计算机的ip
adb -s <device_name> reverse tcp:backend_port tcp:backend_port
现在,您可以在组件中使用如下所示
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
}
});
从“React”导入React;
从“react native”导入{View、Image、TextInput、TouchableOpacity、样式表、ImageBackground、AsyncStorage};
从'native base'导入{Text,Button};
导出类登录扩展React.Component{
建造师(道具){
超级(道具);
this.state={用户名:'',密码:'}
}
登录=()=>{
取('http://localhost:3000/users',{
方法:'POST',
标题:{
“接受”:“应用程序/json”,
“内容类型”:“应用程序/json”
},
正文:JSON.stringify({
用户名:this.state.username,
密码:this.state.password
})
})
.then((response)=>response.json())
。然后((res)=>{
如果(res.success==true){
var username=res.message;
AsyncStorage.setItem('username',username);
this.props.navigation.navigate('app');
警报(“登录成功”);
}否则{
警报(“无效凭证”);
}
})
.完成();
}
render(){
返回(
-欢迎光临-
this.setState({username})}
值={this.state.username}>
this.setState({password})}
值={this.state.password}>
登录
);
}
}
const styles=StyleSheet.create({
容器:{
弹性:1,
},
内容:{
不透明度:0.9,
背景颜色:'白色',
边界宽度:2,
差额:10,
对齐项目:“居中”,
},
标志:{
为内容辩护:“中心”,
对齐项目:“居中”,
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
}
});
{
expo host :http://192.168.0.109:{Your Port}/The name for your API
}
ngrok http (port no of backend services)
eg:ngrok http 8081
http://10.0.2.2:3000
http://localhost:3000